0

I've got a function called compute() that does a bunch of computations and then updates the values of an HTML table, triggered by a click() event. This is not an ajax call, just several for loops.

What I'd like to do is provide a visual indicator that the computation is running. Something like modifying the opacity of the table. I thought that something like the following could work :

$("#mytable").css("opacity", "0.5");
compute();
$("#mytable").css("opacity", "1");

But when I use this code the opacity does not seem to be modified.

Any hint on how to do this ?

Many thanks in advance !

juba
  • 47,631
  • 14
  • 113
  • 118

3 Answers3

2

That's because the UI is not updated between the modification of the opacity and the compute(); function. UI is updated once a while, not after every line of code (that would slow everything down).

You can use a timeout to bypass that: setTimeout(compute, 0);.

That way your UI get's updated before running compute(). You do have to put the third line, where you modify the opacity back to 1, in that function because it will run before compute() is done.

$("#mytable").css("opacity", "0.5");
setTimeout(compute, 0);

function compute() {
    ...

    $("#mytable").css("opacity", "1");
}

It might look dirty at first, but it is a genuine way to make sure your UI is updated!

Tim S.
  • 13,597
  • 7
  • 46
  • 72
  • Ah, yes, this works ! In fact I already tried something like this, but I left the parentheses : `setTimeout(compute(), 0);` And this does not work. Thanks a lot ! – juba Nov 23 '12 at 15:02
  • You are very welcome @juba. The setTimeout and setInterval method require a function. You can set a function inline: `setTimeout(function() { /* do stuff */ }, 1000);` or use the function name: `setTimeout(function_name, 1000);`. If you add the parentheses, the argument will be set whatever the function returns. – Tim S. Nov 23 '12 at 15:11
  • Just to clarify why this doesn't work if you let the parentheses : http://stackoverflow.com/questions/8058996/why-does-calling-settimeout-with-parenthesis-not-start-a-new-callstack – juba Nov 26 '12 at 07:52
0

All client side implementations of JavaScript are single threaded, so you can't really expect the function-call compute to carry on running while the next statement is being executed.
If you want you could use a web worker, though, to sort-of spawn a background thread.

After reading your question a second time, I must say that @tomdemuyt could very well be right: it's very likely that compute executes so quickly that the opacity is changed twice in a split second, so fast that you hardly notice it changing. also, since this is an event handler, you might want to consider this:

function compute(e)
{
    $(this).css({opacity:'.5'});
    //rest of your code
    $(this).css({opacity:'1'});
}
$('#mytable').on('click',compute);

which is just a bit more tidy IMO - it could be that this is not applicable to your code, but just in case...

Elias Van Ootegem
  • 74,482
  • 9
  • 111
  • 149
0

Most likely this is because your compute() function executes so quickly that you don't perceive the opacity changes.

Try to place a break-point in compute(), let us know whether the opacity changed.

tomdemuyt
  • 4,572
  • 2
  • 31
  • 60