https://developer.mozilla.org/zh-CN/docs/Web/Web_Components/Using_shadow_DOM
- Web components 的一个重要属性是封装——可以将标记结构、样式和行为隐藏起来,并与页面上的其他代码相隔离,保证不同的部分不会混在一起,可使代码更加干净、整洁
- 注释:每个Shadow DOM都有一个根节点,这个根节点挂载到正常dom下,作为它的子节点。
- 你可以使用同样的方式来操作 Shadow DOM,就和操作常规 DOM 一样——例如添加子节点、设置属性,以及为节点添加自己的样式(例如通过 element.style 属性),或者为整个 Shadow DOM 添加样式(例如在 <style> 元素内添加样式)
- Shadow DOM 内部的元素始终不会影响到它外部的元素(除了 :focus-within),这为封装提供了便利
- 注释::focus-within 是一个CSS 伪类 ,表示一个元素获得焦点,或,该元素的后代元素获得焦点。换句话说,元素自身或者它的某个后代匹配 :focus 伪类
- 注释:外部也不会影响到内部
- 默认播放控制按钮的 <video> 元素为例。你所能看到的只是一个 <video> 标签,实际上,在它的 Shadow DOM 中,包含了一系列的按钮和其他控制器。Shadow DOM 标准允许你为你自己的元素(custom element)维护一组 Shadow DOM。
- 可以使用 Element.attachShadow() 方法来将一个 shadow root 附加到任何一个元素上。它接受一个配置对象作为参数,该对象有一个 mode 属性,值可以是 open 或者 closed:
- open 表示可以通过页面内的 JavaScript 方法来获取 Shadow DOM,例如使用 Element.shadowRoot 属性:
- 注释:elementRef.attachShadow 是把一个 dom 结构渲染成 Shadow DOM。然后这个 shadow 可以像普通 dom 一样,通过 appendChild 添加到其他 dom 上
let shadow = elementRef.attachShadow({mode: 'open'});
let shadow = elementRef.attachShadow({mode: 'closed'});
- 浏览器中的某些内置元素就是如此,例如<video>,包含了不可访问的 Shadow DOM
- 实现一个示例
- 在构造函数中,我们首先将 Shadow root 附加到 custom element 上:
- 注释:class 的方式可以通过 this.attachShadow 去声明一个容器,然后把根节点添加到这个容器上,从而把这个根节点创造为Shadow DOM
class PopUpInfo extends HTMLElement {
constructor() {
// 必须首先调用 super 方法
super();
// 创建 shadow root
var shadow = this.attachShadow({mode: 'open'});
// 将所创建的元素添加到 Shadow DOM 上
shadow.appendChild(style);
shadow.appendChild(wrapper);
wrapper.appendChild(icon);
wrapper.appendChild(info);
// 元素的具体功能写在下面
...
}
}
- 因为<link> 元素不会打断 shadow root 的绘制,因此在加载样式表时可能会出现未添加样式内容(FOUC),导致闪烁