javascript - dispatchEvent 产生无序的调用捕获/冒泡监听器

标签 javascript google-chrome firefox safari dom-events

当我使用 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/

相关文章:

javascript - 如何记录集合中每个模型的特定字段

java - 从 JApplet 读取文件

javascript - 库使用 localStorage - Chrome 网上应用店

html - 为什么 firebug 会自动插入 </p>?

Firefox "slide"悬停过渡

javascript - 如何使用join方法在数组中的名称之间添加逗号-Javascript

javascript - React 路由器链接不断推送到历史相同的 url?

javascript - JavaScript 中的字符串转 JSON 格式

css - Chrome 在 <picture> HTML5 中加载 2 张图片

尝试检索图像链接时出现 Python 错误