ShadowRoot

Baseline 广泛可用 *

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

* 此特性的某些部分可能存在不同级别的支持。

ShadowRoot 接口是 Shadow DOM API 的一个接口,它是一个 DOM 子树的根节点,该子树独立于文档的主 DOM 树进行渲染。

你可以通过元素的 Element.shadowRoot 属性来获取对该元素阴影根的引用,前提是该阴影根是使用 Element.attachShadow() 方法创建的,并且 mode 选项设置为 open

EventTarget Node DocumentFragment ShadowRoot

实例属性

ShadowRoot.activeElement 只读

返回阴影树中具有焦点的 Element

ShadowRoot.adoptedStyleSheets

添加一个构造样式表数组,供阴影 DOM 子树使用。这些样式表可以与其他共享相同父 Document 节点以及文档本身的 DOM 子树共享。

ShadowRoot.clonable 只读

一个布尔值,指示阴影根是否可克隆。

ShadowRoot.delegatesFocus 只读

一个布尔值,指示当选择了一个不可聚焦的节点时,阴影根是否会将焦点委托给它。

ShadowRoot.fullscreenElement 只读

当前在该阴影树中处于全屏模式的元素。

ShadowRoot.host 只读

返回一个对 ShadowRoot 所附着的 DOM 元素的引用。

ShadowRoot.innerHTML

设置或返回对 ShadowRoot 内部 DOM 树的引用。

ShadowRoot.mode 只读

ShadowRoot 的模式,可以是 openclosed。这决定了阴影根的内部功能是否可以从 JavaScript 访问。

ShadowRoot.pictureInPictureElement 只读

返回阴影树中当前处于画中画模式的 Element

ShadowRoot.pointerLockElement 只读

返回在指针被锁定期间被设置为鼠标事件目标(target)的 Element。如果锁定正在进行中、指针已解锁或目标位于其他树中,则返回 null

ShadowRoot.serializable 只读

一个布尔值,指示阴影根是否可序列化。当其 options.serializableShadowRoots 参数设置为 true 时,元素内的可序列化阴影根将被 Element.getHTML()ShadowRoot.getHTML() 序列化。这在创建阴影根时设置。

ShadowRoot.slotAssignment 只读

返回一个字符串,包含插槽分配的类型,可以是 manualnamed

ShadowRoot.styleSheets 只读

返回一个 StyleSheetList,其中包含显式链接到阴影树或嵌入在阴影树中的样式表的 CSSStyleSheet 对象。

实例方法

ShadowRoot.getAnimations()

返回当前生效的所有 Animation 对象的数组,这些对象的 target 元素是阴影树的后代。

ShadowRoot.getSelection() 非标准

返回一个 Selection 对象,表示用户选择的文本范围,或光标的当前位置。

ShadowRoot.elementFromPoint() 非标准

返回指定坐标处的顶层元素。

ShadowRoot.elementsFromPoint() 非标准

返回指定坐标处的所有元素的数组。

ShadowRoot.setHTML()

提供了一种 XSS 安全的方法,将 HTML 字符串解析并清理成一个 DocumentFragment,然后替换阴影 DOM 中的现有树。

ShadowRoot.setHTMLUnsafe()

将 HTML 字符串解析成一个文档片段,但不进行清理,然后替换阴影根的原始子树。HTML 字符串可以包含声明式阴影根,当使用 ShadowRoot.innerHTML 设置 HTML 时,这些阴影根将被解析为 template 元素。

事件

通过从 HTMLSlotElement 冒泡的事件,ShadowRoot 可以获得以下事件:

HTMLSlotElement slotchange 事件

当插槽中包含的节点发生变化时触发的事件。

示例

以下代码片段摘自我们的 life-cycle-callbacks 示例(也可以 实时查看),该示例创建了一个元素,该元素显示一个由元素属性指定的尺寸和颜色的正方形。

<custom-square> 元素的类定义中,我们包含了一些生命周期回调,它们调用了一个外部函数 updateStyle(),该函数实际上将尺寸和颜色应用于元素。您会看到我们正在将其 this(即自定义元素本身)作为参数传递。

js
class Square extends HTMLElement {
  // …
  connectedCallback() {
    console.log("Custom square element added to page.");
    updateStyle(this);
  }

  attributeChangedCallback(name, oldValue, newValue) {
    console.log("Custom square element attributes changed.");
    updateStyle(this);
  }
  // …
}

updateStyle() 函数本身中,我们使用 Element.shadowRoot 获取对阴影 DOM 的引用。然后,我们使用标准的 DOM 遍历技术找到阴影 DOM 中的 <style> 元素,并更新其中找到的 CSS。

js
function updateStyle(elem) {
  const shadow = elem.shadowRoot;
  const childNodes = shadow.childNodes;
  for (const node of childNodes) {
    if (node.nodeName === "STYLE") {
      node.textContent = `
div {
  width: ${elem.getAttribute("l")}px;
  height: ${elem.getAttribute("l")}px;
  background-color: ${elem.getAttribute("c")};
}
      `;
    }
  }
}

规范

规范
DOM
# interface-shadowroot

浏览器兼容性

另见