当我使用 dispatchEvent
模拟鼠标事件时,事件监听器的调用顺序与实际鼠标事件不同。特别是,某些bubble监听器会在同一目标上的capture监听器之前被调用。
这是一个 fiddle 来说明我的意思:http://jsfiddle.net/soney/8stNc/2/
我在其中写道:
function logFN(message) {
return function() {
console.log(message);
};
}
var event_type = "click";
addEventListener(event_type, logFN("Capture 1"), true);
addEventListener(event_type, logFN("Bubble 1"), false);
addEventListener(event_type, logFN("Capture 2"), true);
addEventListener(event_type, logFN("Bubble 2"), false);
var ev = document.createEvent("MouseEvent");
ev.initMouseEvent(event_type, true, true, window,
0, 0, 0, 0, 0, false, false, false, false, 0, null);
dispatchEvent(ev);
使用模拟鼠标事件(如上面代码中生成的),顺序为:
Capture 1
Bubble 1
Capture 2
Bubble 2
对于实际鼠标事件,顺序是我所期望的:
Capture 1
Capture 2
Bubble 1
Bubble 2
我已在最新版本的 Chrome、Firefox 和 Safari 中对此进行了测试。所有三个浏览器都会产生相同的行为,因此这可能不是一个错误。谁能解释为什么顺序不同以及如何通过模拟事件产生“真实”顺序?
最佳答案
这种差异不是由模拟鼠标事件和真实鼠标事件之间的差异引起的;而是由模拟鼠标事件和真实鼠标事件之间的差异引起的。这是由不同的事件目标引起的。
我生成的“模拟”鼠标事件的事件目标是窗口
。我生成的“真实”鼠标事件的目标比 window
更具体,例如 document.body
。
当事件目标与调用 addEventListener
的对象相同时,将按照添加顺序调用监听器,如下所述:Event listeners registered for capturing phase not triggered before bubbling - why?
对于模拟事件,事件目标与调用它们的监听器的对象相同,因此捕获/冒泡区别对于 JavaScript 的事件模型并不重要。
对于真实事件,事件目标不是调用监听器的对象,因此捕获/冒泡的区别很重要。
关于javascript - dispatchEvent 产生无序的调用捕获/冒泡监听器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25066941/