On 2006-04-19 22:35:44 +0200, Randy Webb <Hi************@aol.com> said:
di*****@gmail.com said the following on 4/19/2006 3:32 PM: I have some code like:
try {
someButton.disabled = true;
cpuIntensiveCode();
} finally {
someButton.disabled = false;
}
The problem is that someButton is never disabled, because the browser
is busy thinking in cpuIntensiveCode.
It is disabled, it just hasn't changed view on the browser window.
actually, it is not disabled, but neither will the browser acknowledge
any user activity while the code is running. It may remember any clicks
and later call any callback methods that should have been called, of
forget them.
Indeed, if I don't reenable someButton in the finally part, it waits
until cpuIntensiveCode is over to disable someButton.
No, it waits until it is completed to continue execution at which time
it would show the disabled button even though the button was disabled
to start with.
Actually, it seems the behavior of interface elements is not updated
much sooner than their graphical display. If a button is showed as
disabled you cannot click it, even if you just fired some code which
enables it but that code is not completed. That may depend on browsers
though. I can't test with IE.
The only way to disable someButton before cpuIntensiveCode is to force
the browser to redraw the window (eg: by putting an alert(...) just
after someButton is disabled).
Read above. Use a settimeout and you will see the difference:
try {
someButton.disabled = true;
window.setTimeout(cpuIntensiveCode,100);
} finally {
someButton.disabled = false;
}
Browsers don't update the display while the code that initiated the
updates is still running.
so, setTimeout is indeed the way to go, because it creates a sort of
"thread" that may execute very quickly and as soon as it's done, the
browser will redraw whatever was affected by that thread.
But the above example won't work as intended. The "CPU intensive code"
will be executed in a separate thread, completely outside of the try()
statement. So, yes, the button will be disabled immediately, but it
will also be re-enabled after 100ms, whether the CPU intensive code is
completed or not (only the setTimeout call must be completed, which
shouldn't take too long).
What you should do is the opposite :
try {
window.setTimeout("someButton.disabled = true", 1)
cpuIntensiveCode
} finally {
someButton.disabled = false
}
What this code does is detach a small thread that will execute almost
immediately (you may not want to rely on the button being unable to
intercept another onclick event, since many things can happen during
one millisecond) and change a property of the button. Since that thread
will be completed, the browser will redraw the button and handle user
events accordingly.
Meanwhile, the main thread will compute your intensive code, and won't
re-enable the button until that code is finished, since the re-enabling
code is part of the same thread.