简体   繁体   中英

Javascript: Atomicity / Interactions between browser view and DOM

I have two specific Javascript questions that are probably answered by one general answer. Please feel free to also submit the corresponding general question--I have difficulties expressing myself.

  • When I manipulate multiple DOM elements in a single Javascript callback, is the view possibly updated "live" with each individual manipulation, or atomically after the callback returns?

  • When a user clicks an HTML element twice in a short timeframe, and the corresponding click handler disables the HTML element, is there a guarantee that the handler won't be executed twice?

Preemptively, I do not have a standards citation for this. This is strictly in my experience.

I have never noticed the visible pixels update while Javascript is executing in real time. I suspect that they will not during the standard operation of the browser - it certainly is possible that debugging presents an exception. I have, however, observed synchronous reflow calculations occurring on DOM elements between the top and bottom of a single function call, but these reflow calculations never made it to the pixel buffer ( that I noticed ). These appear to occur synchronously.

function foo() {
    $('#myElement').width(); // 100
    $('#myElement').parent().width(); // 150
    $('#myElement').css('width', 200);
    $('#myElement').width(); // 200
    $('#myElement').parent().width(); // 250
}

Regarding multiple clicks on an element that is disabled within the click handler, I suspect that the second click will not fire. I believe when the operating system receives a click event it passes it to the browser and it is placed in a queue. This queue is serviced by the same thread that executes Javascript. The OS click event will remain in the queue until Javascript completes execution at which time it will be removed, wrapped as a browser click event, and bubbled through the DOM. At this point the button will already be disabled and the click event will not activate it.

I'm guessing the pixel buffer is painted on-screen as another operation of this same thread though I may be mistaken.

This is based on my vague recollection of standards that I have seen quoted and referenced elsewhere. I don't have any links.

First Bullet: The updates will be live. For example, attach the following function to an onclick handler:

function(){
    var d = document.getElementById("myelement") 
    d.setAttribute("align", "center")
    d.setAttribute("data-foo","bar")
    d.setAttribute("data-bar","baz")
}

Now load this in your browser set a breakpoint on the first line. trigger the event and step through line-by-line while watching the DOM. The updates will happen live, they are not going to happen all at once.

If you want them to happen atomically, you'll want to clone the DOM element in question, make the changes on the clone, then replace the original element with the clone. The cloned element is still being updated in realtime, but the user-visible effect is atomic.

Second Bullet: If the second click event comes in after the element has been disabled, then yes, you won't get a second callback. But if there is any delay between the first click and the disable call, (for example some kind of lengthy check needs to be performed to determine if the element should be disabled) and the second click occurs in that delay, it will fire the callback a second time. The browser has no way to know that multiple click events isn't acceptable behavior in a given script.

All script executions happen within the same thread. Therefore you can never have simultaneous actions and don't have to worry about concurrent modification of elements. This also means you don't need to worry about a click handler being fired while one is currently executed. However, this doesn't mean they cant immediately fire it again when your script is finished. The execution may be so fast that its indistinguishable.

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