简体   繁体   中英

javascript onclick order of events

I have a button to perform a calculation and an indicator:

<button class="btn" type="button" onclick="$('#busy').show(); calculate();">Ok</button>
<div id="busy" style="display: none;">Calculating...</div>

What the browser does in this case is calculate(), and then show the div Same problem when the calculate() function first tries to show the div and then calculates.

How do I make the events happen in the intended order?

EDIT: Maybe the css does change before the calculation, but it is not rendered until after the calculation. Also tried with click event handling but same thing.

http://jsfiddle.net/Z7rAJ/

jQuery's .show() does nothing else than performing a change in the display css property (alongside some magic on previous states).

However, everything happens in syncronized code. Its virtually impossible that your calculate() method is called first here.


Its much more likely that your calculate() method is doing some heavy synronized, blocking operations and that the browser batches the two code segements together. It happens to be that in browsers, Javascript code, CSS Rendering and general "UI repaints and reflows", are processed in the same queue and therefore in the same thread. I'm talking about the such called " UI Queue " here.

In short words, you need to make your calculate() function "faster", decouple it into smaller chunks. The worst option would be to entirely defer the calling of calculate() by invoking a setTimeout . That latter would solve your immediate problem, but it would still block the browser and the UI queue afterwards.

Example: http://jsfiddle.net/5E2bn/1/

As I already stated, you don't really want to do that, its just an example to make the point clear. In any real-world scenario you should go back to the drawing board and think about what calculate() does here and how you can split it up into smaller chunks.

One very convenient way to decouple long-running processes in Javascript is the usage of Run-away script timers , which basically chunk a sync loop into multiple asyncronous loops to give the UI queue and the browser time to breath in between code executions.

Do something like coz setTimeout might not be a good option

$('.btn').click(function() {
    if (calculate()) {
        $('#busy').show();
    }
});

Make sure you return true or false : #busy will be shown only once the value from calculate() function is returned

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM