javascript - 为什么事件冒泡在分离的 DOM 元素中不起作用?

标签 javascript google-chrome dom dom-events

我有一个 parent <div>和一个 child <div>在内存中 - 未附加到当前文档。我想触发 CustomEvent在 child 身上,但听 parent 的那个事件。这是我的代码:

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);

此代码未按预期工作。 parent 的事件监听器永远不会触发。这似乎与事件从目标冒泡的 JavaScript 事件系统相矛盾。但是,如果我将此代码段的最后两行修改为以下内容,回调将按照我的预期触发:

document.body.appendChild(parent);
child.dispatchEvent(event);

换句话说,如果我在分派(dispatch)事件之前将我的片段附加为文档的子树,那么父事件监听器将完全按预期触发。为什么?在使用分离的 DOM 元素时有没有办法允许冒泡?

最佳答案

Why [doesn't bubbling work on detached elements]?

为了回答您的第一个问题,我查看了 W3C "UI Events (formerly DOM Level 3 Events)" spec ,并且没有看到任何专门解决此问题的内容。然而,event phase部分提到了一些使这种行为看起来合理的事情。

As the next step, the event object must complete one or more event phases. This specification defines three event phases: capture phase, target phase and bubble phase. Event objects complete these phases in the specified order using the partial propagation paths as defined below. A phase must be skipped if it is not supported, or if the event object's propagation has been stopped. For example, if the Event.bubbles attribute is set to false, the bubble phase will be skipped, and if Event.stopPropagation() has been called prior to the dispatch, all phases must be skipped.

强调我的。

然后规范继续列出阶段:

  1. The capture phase: The event object must propagate through the target's ancestors from the Window to the target's parent. This phase is also known as the capturing phase. Event listeners registered for this phase must handle the event before it reaches its target.
  2. The target phase: The event object must arrive at the event object's event target. This phase is also known as the at-target phase. Event listeners registered for this phase must handle the event once it has reached its target. If the event type indicates that the event must not bubble, the event object must halt after completion of this phase.
  3. The bubble phase: The event object propagates through the target's ancestors in reverse order, starting with the target's parent and ending with the Window. This phase is also known as the bubbling phase. Event listeners registered for this phase must handle the event after it has reached its target.

再次强调我的。规范从不明确指出分离元素会发生什么。鉴于目标和气泡阶段需要从元素到窗口的路径,并且在分离元素上不可能有路径,因此必须跳过目标和气泡事件阶段,因为这些路径不受支持。

Is there a way to allow bubbling when using detached DOM elements?

据我所知,没有任何允许冒泡的内置功能。您也许可以使用一些自定义代码来伪造冒泡,但这需要在每次触发事件时检查元素是否已分离。

另一个想法是将元素添加到 DOM,触发事件,然后分离元素。由于我还没有对此进行测试,所以我不知道它是否会起作用。

关于javascript - 为什么事件冒泡在分离的 DOM 元素中不起作用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29583766/

相关文章:

javascript - 为什么Ajax请求改变参数值?

javascript - 如何在密集型任务中渲染 DOM 变化?

javascript - Regex jQuery find ("option:[text^=' "]) 在 ie 8 和 chrome 上出现错误

javascript - Chrome 扩展获取 API - 内容安全策略

java - 如何编写更改 url 的脚本

在 iBooks 中翻页时 Javascript 间歇性触发

javascript - 带有 forEach 函数的 querySelectorAll 不适用于旋转木马幻灯片上的切换按钮

javascript - 使用 JS/RegExp 进行多次替换

javascript - 伪造预加载器屏幕

javascript - 在流行的浏览器中, "console.log"关于执行延迟的最新行为是什么?