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),导致闪烁
posted on 2023-02-23 15:21  噬蛇之牙  阅读(180)  评论(0编辑  收藏  举报