2013-11-27 29 views
1

我有一些代码通过DOM API(createEvent,initEvent,dispatchEvent等)触发/模拟DOM事件。对于大多数DOM事件(如点击),浏览器默认操作就像链接一样。模拟DOM事件的浏览器默认动作的执行

由于JavaScript代码执行是单线程的我不确定当我的代码在批处理中触发多个事件时执行流程如何。所以我们说我这样做(伪代码):

for (var i = 0; i < 10; i++) { 
    var event = document.body.createEvent('MouseEvent'); 
    event.initMouseEvent(...); 
    document.body.dispatchEvent(event); 
} 

会发生什么?我的循环是否首先完全执行,然后处理所有事件,导致默认的浏览器操作触发并注册事件监听器来执行?或者每次调用dispatchEvent触发默认操作(以及事件侦听器)时代码执行都会中断?

感谢

+2

事件在javascript中被阻止。每次迭代都会阻止触发事件,然后继续循环 – megawac

+0

这是否意味着浏览器的默认操作也会立即执行? –

回答

1

因为JS不是多线程的,每一个事件进行调度,这将立即触发时间 - 实现不创建活动的一些队列将在下一个周期发射了。

这是旧的mutation events已被弃用的原因之一。例如,如果将400个元素添加到节点,则会引发400个突变事件(传播),从而减慢几乎所有事情的速度。

因此,在您的代码片段中,循环的每次迭代都将创建鼠标事件,调度鼠标事件,处理鼠标事件的所有侦听器,然后继续执行循环的下一次迭代。

+0

谢谢你的解释。我创建了一个代码示例,您可以在其中看到您的解释。不过,我更关心浏览器的默认操作。您可以在这里看到http://jsbin.com/AGUCuMAf/2/edit?html,js,console,output,只有在调度所有100个事件后,浏览器才会跳转到该锚点。但是,由于每次发送事件时它已经执行了所有关联的侦听器,我们期望它会立即跟随锚点。 –

+0

我相信这是浏览器在运行循环时“挂起”的结果。循环需要很长时间才能完成,因为js只有一个堆栈,所以DOM更新只会在下一个周期发生,除非您有一些明确的代码来启动重排。 – megawac

+0

其实这个例子工作不正常。我正在尝试修复它。但是你提到的是我最初谈论的内容。代码执行中只有一个线程(在本例中为for循环和所有潜在的事件侦听器)和浏览器GUI(浏览器默认操作,在本例中跳转到锚点)。如果立即触发事件并且立即执行附加侦听器,那么使用浏览器默认动作等待for循环完成之前会有点奇怪,不是吗? –