我有一个父母<div>
有一个孩子<div>
在内存中 - 未附加到当前文档。我想触发一个CustomEvent
关注孩子,但听父母的事件。这是我的代码:
var parent = document.createElement('div');
var child = document.createElement('div');
parent.appendChild(child);
parent.addEventListener('boom', function(event) {
console.log('parent listener', event); // <~ This never runs!
});
var event = new CustomEvent('boom', { bubbles: true });
child.dispatchEvent(event);
该代码无法按预期工作。父级上的事件侦听器永远不会触发。这似乎与 JavaScript 事件系统相矛盾,事件从目标中冒出。但是,如果我将此代码段的最后两行修改为以下内容,回调将按照我的预期触发:
document.body.appendChild(parent);
child.dispatchEvent(event);
换句话说,如果我在分派事件之前将片段附加为文档的子树,则父事件侦听器将完全按预期触发。为什么?有没有办法在使用分离的 DOM 元素时允许冒泡?
为什么[冒泡对分离元素不起作用]?
为了回答你的第一个问题,我查看了W3C“UI 事件(以前称为 DOM Level 3 事件)”规范 http://www.w3.org/TR/uievents/,并且没有看到任何专门解决此问题的内容。但是,那事件阶段 http://www.w3.org/TR/uievents/#event-phase部分提到了一些使这种行为看起来合理的事情。
下一步,事件对象必须完成一个或多个事件阶段。该规范定义了三个事件阶段:捕获阶段、目标阶段和冒泡阶段。事件对象使用下面定义的部分传播路径按指定顺序完成这些阶段。如果不支持则必须跳过某个阶段,或者事件对象的传播是否已停止。例如,如果 Event.bubbles 属性设置为 false,则将跳过冒泡阶段,如果在调度之前已调用 Event.stopPropagation(),则必须跳过所有阶段。
强调我的。
然后规范继续列出各个阶段:
- The 捕获阶段: 事件对象必须通过目标的祖先从 Window 传播到目标的父级。该阶段也称为捕获阶段。为此阶段注册的事件侦听器必须在事件到达目标之前对其进行处理。
- The 目标阶段:事件对象必须到达事件对象的事件目标。此阶段也称为目标阶段。一旦事件到达目标,为此阶段注册的事件侦听器必须处理该事件。如果事件类型指示事件不得冒泡,则事件对象必须在此阶段完成后停止。
- The 气泡相: 事件对象以相反的顺序通过目标的祖先传播,从目标的父级开始并以 Window 结束。该阶段也称为冒泡阶段。为此阶段注册的事件侦听器必须在事件到达目标后对其进行处理。
再次强调我的。规范从未明确指出分离元素会发生什么。鉴于目标和冒泡阶段需要从元素到窗口的路径,并且分离元素上不可能有路径,因此必须跳过目标和冒泡事件阶段,因为这些路径不受支持。
有没有办法在使用分离的 DOM 元素时允许冒泡?
据我所知,没有任何内置的东西可以允许冒泡。您也许可以使用一些自定义代码来伪造冒泡,但这需要在每次触发事件时检查该元素是否已分离。
另一个想法是将元素添加到 DOM,触发事件,然后分离元素。由于我还没有测试过,所以我不知道它是否有效。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)