事件:composed 属性

Baseline 已广泛支持

此特性已相当成熟,可在许多设备和浏览器版本上使用。自 ⁨2020 年 1 月⁩ 起,所有主流浏览器均已支持。

注意:此功能在 Web Workers 中可用。

Event 接口中的只读 composed 属性返回一个布尔值,该值指示事件是否会穿过 Shadow DOM 边界传播到标准 DOM。

所有用户代理(UA)分派的 UI 事件都是 composed 的(例如 click/touch/mouseover/copy/paste 等)。大多数其他类型的事件不是 composed 的,因此会返回 false。例如,这包括那些在创建时没有将其 composed 选项设置为 true 的合成事件。

仅当 bubbles 属性也为 true 时,事件才会传播。但是,只有 composed 事件在捕获阶段也会被当作处于 AT_TARGET 阶段进行处理。您可以通过调用 composedPath() 来确定事件将通过 Shadow Root 传播到 DOM Root 的路径。

如果事件在到达 Shadow Root 后会从 Shadow DOM 穿过到标准 DOM,则此布尔值为 true。(即,事件开始传播的 Shadow DOM 中的第一个节点。)

如果此值为 false,则 Shadow Root 将是接收事件的最后一个节点。

示例

在这个 示例 中,我们定义了两个简单的自定义元素:<open-shadow><closed-shadow>。它们都接受其 text 属性的内容,并将其作为 <p> 元素的文本内容插入到元素的 Shadow DOM 中。两者唯一的区别在于它们的 Shadow Root 在附加时,其 mode 分别设置为 openclosed

这两个定义如下所示:

js
customElements.define(
  "open-shadow",
  class extends HTMLElement {
    constructor() {
      super();

      const pElem = document.createElement("p");
      pElem.textContent = this.getAttribute("text");

      const shadowRoot = this.attachShadow({
        mode: "open",
      });

      shadowRoot.appendChild(pElem);
    }
  },
);

customElements.define(
  "closed-shadow",
  class extends HTMLElement {
    constructor() {
      super();

      const pElem = document.createElement("p");
      pElem.textContent = this.getAttribute("text");

      const shadowRoot = this.attachShadow({
        mode: "closed",
      });

      shadowRoot.appendChild(pElem);
    }
  },
);

然后我们在页面中插入了这两个元素各一个。

html
<open-shadow text="I have an open shadow root"></open-shadow>
<closed-shadow text="I have a closed shadow root"></closed-shadow>

然后,我们在 <html> 元素上添加了一个 click 事件监听器。

js
document.querySelector("html").addEventListener("click", (e) => {
  console.log(e.composed);
  console.log(e.composedPath());
});

当您单击 <open-shadow> 元素,然后单击 <closed-shadow> 元素时,您会注意到两件事情。

  1. composed 属性返回 true,因为 click 事件始终能够穿过 Shadow 边界传播。
  2. composedPath 对两个元素的值有所不同。

<open-shadow> 元素的 composed 路径是这样的:

Array [ p, ShadowRoot, open-shadow, body, html, HTMLDocument https://mdn.github.io/web-components-examples/composed-composed-path/, Window ]

<closed-shadow> 元素的 composed 路径如下:

Array [ closed-shadow, body, html, HTMLDocument https://mdn.github.io/web-components-examples/composed-composed-path/, Window ]

在第二种情况下,事件监听器只传播到 <closed-shadow> 元素本身,而不会传播到 Shadow 边界内的节点。

规范

规范
DOM
# ref-for-dom-event-composed①

浏览器兼容性