2

我有两个特定的 Javascript 问题,可能由一个通用答案回答。请随时提交相应的一般性问题——我表达自己有困难。

  • 当我在单个 Javascript 回调中操作多个 DOM 元素时,视图可能会随着每个单独的操作“实时”更新,还是在回调返回后自动更新?

  • 当用户在短时间内两次单击 HTML 元素,并且相应的单击处理程序禁用 HTML 元素时,是否可以保证处理程序不会被执行两次?

4

3 回答 3

1

先发制人,我没有对此的标准引用。这是严格按照我的经验。

我从未注意到Javascript 实时执行时可见像素的更新。我怀疑他们不会在浏览器的标准操作期间 - 调试肯定会出现异常。然而,我观察到在单个函数调用的顶部和底部之间的 DOM 元素上发生同步回流计算,但这些回流计算从未进入像素缓冲区(我注意到了)。这些似乎是同步发生的。

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

关于在单击处理程序中禁用的元素的多次单击,我怀疑第二次单击不会触发。我相信当操作系统收到点击事件时,它会将其传递给浏览器并将其放入队列中。该队列由执行 Javascript 的同一线程提供服务。操作系统点击事件将保留在队列中,直到 Javascript 完成执行,此时它将被删除,包装为浏览器点击事件,并在 DOM 中冒泡。此时按钮已经被禁用,点击事件不会激活它。

我猜像素缓冲区是作为同一线程的另一个操作在屏幕上绘制的,尽管我可能弄错了。

这是基于我对在其他地方引用和引用的标准的模糊回忆。我没有任何链接。

于 2013-10-31T20:17:10.517 回答
0

第一个子弹:更新将是实时的。例如,将以下函数附加到 onclick 处理程序:

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

现在在浏览器中加载它,在第一行设置一个断点。在观察 DOM 的同时触发事件并逐行执行。更新将实时发生,它们不会一下子发生。

如果您希望它们以原子方式发生,您需要克隆有问题的 DOM 元素,对克隆进行更改,然后用克隆替换原始元素。克隆的元素仍在实时更新,但用户可见的效果是原子的。

第二个子弹:如果在元素被禁用后第二次点击事件发生,那么是的,你不会得到第二次回调。但是如果第一次点击和禁用调用之间有任何延迟,(例如,需要执行某种冗长的检查以确定是否应该禁用元素)并且在该延迟中发生第二次点击,它将触发回调第二次。浏览器无法知道在给定脚本中多次点击事件是不可接受的行为。

于 2013-10-31T18:26:45.840 回答
0

所有脚本执行都发生在同一个线程中。因此,您永远不会同时执行操作,也不必担心元素的并发修改。这也意味着您无需担心在当前执行单击处理程序时会触发单击处理程序。但是,这并不意味着他们不能在您的脚本完成后立即再次触发它。执行速度可能如此之快,以至于无法区分。

于 2013-10-31T18:28:17.553 回答