简体   繁体   English

Javascript:原子性/浏览器视图与DOM之间的相互作用

[英]Javascript: Atomicity / Interactions between browser view and DOM

I have two specific Javascript questions that are probably answered by one general answer. 我有两个特定的Javascript问题,可能由一个一般性答案回答。 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? 当我在单个Javascript回调中操作多个DOM元素时,视图是否可能通过每个单独的操作“实时”更新,或者在回调返回后自动更新?

  • 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? 当用户在短时间内单击HTML元素两次,并且相应的单击处理程序禁用了HTML元素时,是否可以保证不会两次执行该处理程序?

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. 我从未注意到Javascript实时执行时可见像素的更新。 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 ). 但是,我观察到在单个函数调用的顶部和底部之间的DOM元素上发生了同步重排计算,但是这些重排计算从未到达像素缓冲区(我注意到)。 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. 该队列由执行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. 操作系统单击事件将保留在队列中,直到Javascript完成执行为止,此时将其删除,包装为浏览器单击事件,并在DOM中冒泡。 At this point the button will already be disabled and the click event will not activate it. 此时,该按钮将已经被禁用,而click事件将不会激活它。

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: 例如,将以下函数附加到onclick处理程序:

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. 触发事件并在观看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. 如果您希望它们以原子方式发生,则需要克隆有问题的DOM元素,在克隆上进行更改,然后用克隆替换原始元素。 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. 第二个项目符号:如果在元素被禁用之后出现了第二个click事件,那么是的,您将不会获得第二个回调。 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. 执行速度可能如此之快以至于无法区分。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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