为什么事件冒泡在分离的DOM元素中不起作用? [英] Why doesn't event bubbling work in detached DOM elements?

查看:66
本文介绍了为什么事件冒泡在分离的DOM元素中不起作用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个父级<div>,内存中有一个子级<div>-未附加到当前文档中.我想在子级上触发CustomEvent,但要从父级监听该事件.这是我的代码:

I have a parent <div> with one child <div> in memory - not attached to the current document. I want to trigger a CustomEvent on the child but listen to that event from the parent. Here is my code:

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事件系统的矛盾,在JavaScript事件系统中,事件从目标冒泡.但是,如果我将该代码段的最后两行修改为以下内容,则会触发回调,就像我期望的那样:

This code doesn't work as expected. The event listener on the parent never fires. This seems to be a contradiction of the JavaScript event system whereby events bubble up from the target. However, if I modify the final two lines of this snippet to the following, the callback fires as I would expect it to:

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

换句话说,如果我在分派事件之前将片段作为文档的子树追加,则父事件侦听器将完全按预期触发.为什么?使用分离的DOM元素时是否有办法允许冒泡?

In other words, if I append my fragment as a subtree of the document before dispatching the event, then the parent event listener fires exactly as expected. Why? Is there a way to allow bubbling when using detached DOM elements?

推荐答案

为什么[不对分离元素进行冒泡工作?]

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

为回答您的第一个问题,我查看了 W3C"UI事件(以前为DOM Level 3事件) " ,并且没有发现任何可以专门解决此问题的东西.但是,事件阶段部分提到了一些使此行为看起来合理的事情.

To answer your first question, I looked at the W3C "UI Events (formerly DOM Level 3 Events)" spec, and didn't see anything that addressed this issue specifically. However, the event phase portion mentions a few things that makes this behavior seem reasonable.

下一步,事件对象必须完成一个或多个事件阶段.该规范定义了三个事件阶段:捕获阶段,目标阶段和气泡阶段.事件对象使用下面定义的部分传播路径以指定的顺序完成这些阶段. 如果不支持该阶段,或者事件对象的传播已停止,则必须跳过该阶段.例如,如果Event.bubbles属性设置为false,则将跳过冒泡阶段,如果在分发之前已调用Event.stopPropagation(),则必须跳过所有阶段.

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.

强调我的.

然后该规范继续列出各个阶段:

The spec then goes on to list the phases:

  1. 捕获阶段:事件对象必须通过目标的祖先从Window传播到目标的父对象.此阶段也称为捕获阶段.在此阶段注册的事件侦听器必须在事件到达目标之前对其进行处理.
  2. 目标阶段:事件对象必须到达事件对象的事件目标.此阶段也称为目标阶段.一旦事件到达目标,为此阶段注册的事件侦听器必须处理该事件.如果事件类型指示该事件一定不能冒泡,则该事件对象必须在此阶段完成后停止.
  3. 泡沫阶段:事件对象以相反的顺序从目标的祖先传播,从目标的父对象开始,然后以Window结束.此阶段也称为冒泡阶段.在此阶段注册的事件侦听器在达到目标后必须处理该事件.
  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.

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

Again, emphasis mine. The spec never calls out what happens with detached elements explicitly. Given that the target and bubble phases require the path to go from the element to the window, and that no path is possible on detached elements, it follows that the target and bubble event phases must be skipped because those paths are not supported.

使用分离的DOM元素时是否有办法允许冒泡?

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

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

As far as I can tell, there's nothing built-in that would allow bubbling. You might be able to fake bubbling with some custom code, but that would require checking whether the element is detached every time you trigger an event.

另一种想法是将元素添加到DOM,触发事件并分离元素.因为我还没有测试过,所以我不知道它是否可以工作.

Another thought would be to add the elements to the DOM, trigger the event, and detach the elements. As I haven't tested this, I have no idea whether it would work.

这篇关于为什么事件冒泡在分离的DOM元素中不起作用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆