介绍
Shadow DOM 是 Web 组件规范的一部分,它允许将封装的“影子” DOM 树附加到常规 DOM 树中的元素。影子 DOM 封装了 DOM 和样式,使开发人员可以控制这些元素,而不会与页面上的其他代码或样式发生冲突。
术语
- 影子宿主(Shadow host):影子 DOM 附加到的常规 DOM 节点。
- 影子树(Shadow tree):影子 DOM 内部的 DOM 树。
- 影子边界(Shadow boundary):影子 DOM 终止,常规 DOM 开始的地方。
- 影子根(Shadow root):影子树的根节点。
创建 Shadow DOM
const host = document.querySelector('#host')
// 创建一个 Shandow DOM 元素
const shadow = host.attachShadow({mode: 'open'})
const span = document.createElement('span')
span.textContent = 'Hello World'
// 向 Shadow DOM 元素内填充内容
shadow.appendChild(span)
Shadow DOM 无法通过寻常方式来对里面的元素进行操作。
mode 选项
- open:Shadow DOM 元素及其内容是可被 JavaScript 访问的,可以通过影子宿主的 shadowRoot 属性访问影子 DOM 的内部。
- closed:Shadow DOM 元素及其内容是封闭的,无法被 JavaScript 访问。
访问 Shadow DOM 元素
通过 host.shadowRoot 方式来访问内部的 Shadow DOM 元素。
const host = document.querySelector('#host')
const shadow = host.attachShadow({ mode: "open" });
...
// 获取 Shadow DOM 元素
host.shadowRoot.querySelector('span')
css 样式
页面上的 css 样式不会影响到 Shadow DOM 元素,反之亦然。
想要在 Shadow DOM 元素上应用样式,有两种方式:
- 编程式,通过构建一个 CSSStyleSheet 对象并将其附加达到影子根。
- 声明式,通过在一个 template 元素的声明中添加一个 style 元素。
编程式
// 创建一个 CSSStyleSheet 对象
const sheet = new CSSStyleSheet();
sheet.replaceSync('span {color: red; border: 2px dotted black;}');
const host = document.querySelector('#host');
const shadow = host.attachShadow({mode: 'open'})
// 将样式表对象附加到影子根
shadow.adoptedStyleSheets = [sheet]
声明式
通过在 template 元素中添加一个 style 元素,然后将其附加到影子根。
<template id="my-element">
<style>
span {color: red; border: 2px dotted black;}
</style>
<span>Hello World</span>
</template>
<div id="host"></div>
// 获取 template 元素
const template = document.querySelector('#my-element')
const host = document.querySelector('#host')
const shadow = host.attachShadow({mode: 'open'})
// 将 template 元素的内容附加到影子根
shadow.appendChild(template.content);
自定义组件
通过 Shadow DOM 能够自定义组件,配合 customElemets.define() 来创建自定义组件。
详情