发布于 2026-01-06 1 阅读
0

Web Components、Shadow DOM、Shadow CSS;tldr

Web Components、Shadow DOM、Shadow CSS;tldr

我不会告诉你你应该立刻投入到 Web Components 中,也不会告诉你它是会取代你现有框架的全新酷炫玩意儿。

我正在尝试尽可能高效地解答以下问题,以便您更好地理解:

  1. 什么是 Web 组件?
  2. 什么是 Shadow DOM?
  3. 什么是插槽(以及什么是LightDOM)?
  4. 使用 Shadow DOM 时需要哪些 CSS 选择器?

1. 什么是 Web 组件?

Web组件是指通过customElements.define接口定义的任何内容。

无论你使用 Shadow DOM 还是其他什么技术,只要你使用该 API 来创建自定义标签,你就是在使用 Web 组件。

1.1. 如何使用 Web 组件?

<your-tag></your-tag>
<script>
// most simple example of a Web Component:
customElements.define('your-tag', class extends HTMLElement {
  connectedCallback() {
    this.innerHTML = 'Hello world!';
  }
}
</script>
Enter fullscreen mode Exit fullscreen mode

它们不会自动关闭,所以不要这样做!

1.2. Web组件的生命周期

在您的 Web 组件中,您可能会经常用到以下5 种方法中的 4 种:

  • constructor()用于数据预取等。
  • connectedCallback()它会告诉你它何时被挂载到DOM中。
  • disconnectedCallback()它会告诉你何时从 DOM 中卸载。
  • attributeChangedCallback(...)它会告诉你元素上的某个属性何时发生了变化
    • 这个功能与另一个功能结合使用,static get observedAttributes() {return ['foo', 'bar']; }后者指定要观察哪些属性并调用回调函数。

2. 什么是 Shadow DOM?

customElements.define('your-tag', class extends HTMLElement {
  connectedCallback() {
    this.innerHTML = 'Hello Light';
    const shadowRoot = this.attachShadow({ mode: 'open' });
    shadowRoot.innerHTML = 'Hello Darkness';
  }
}

Enter fullscreen mode Exit fullscreen mode

首先,Shadow DOM 和其他 DOM 节点一样,也是一个 DOM 节点。
然而,Shadow DOM 节点本身无法通过 `<div>` 属性找到,其内部的元素也无法从外部querySelector通过 `<div>` 属性找到。 此外,外部 CSS 样式对 Shadow DOM 也无效。querySelector

几点简要说明:

影子 DOM ...

  • 不是安全层!
  • 不会排除 JS 的作用域。
  • CSS 和 HTML 的作用域
  • videoplayer这意味着,如果您在文档中定义了样式和库,它们将无法在您的 Shadow DOM 中找到任何 DOM,也无法对其中的任何元素应用任何样式。

2.1. 如果我的文档中有一个全局库,say其中包含一个方法,hello()我可以从 Shadow DOM 内部调用它吗?

是的!请看:https://codesandbox.io/s/say-hello-qswww?
file=/src/index.js 您可以在普通的 JS 作用域中定义 Web 组件。

2.2. 为什么需要 Shadow DOM?

这里我只看到了两个答案:

  • 你需要隔离 CSS/HTML
  • 您想使用老虎机功能

3. 什么是插槽?什么是轻量级DOM?

3.1. 轻型DOM

轻量级 DOM ≠ 普通 DOM。轻量级 DOM 指的是 ShadowDOM Web 组件中不在 Shadow DOM 中的 DOM。

如果您查看我的在线示例,您会发现看不到 Light DOM 内容(“Hello Light”),因为 Shadow DOM 内容会在 Web 组件附加后接管其功能。Light DOM 只能通过插槽(下一节)进行引用。

3.2. 插槽

如果你<slot><slot>在 Shadow DOM 中的任何位置放置内容,并且 Light DOM 中有内容,那么在第 3.1 节中“丢失”的 Light DOM 中的内容将显示在它所<slot>在的位置。

它实际上是一个占位符,其作用就像将插槽中的内容复制到插槽所在的确切位置一样。所以你可以这样理解:标签所在的位置,<slot>Shadow DOM 外部的所有内容都会(虚拟地)“复制”到那里。

https://codesandbox.io/s/light-dom-vs-shadow-dom-cmyh9?file=/src/index.js

4. 使用 Shadow DOM 时需要哪些 CSS 选择器?

您很可能需要以下物品:

  • ::slotted()
  • :host()
  • :host-context()

我创建了一个沙盒环境,希望能帮助大家理解它的工作原理(如果需要更详细的文字解释,请在评论区留言):

https://codesandbox.io/s/gracious-saha-928yt?file=/index.html

来源

文章来源:https://dev.to/activenode/web-components-shadow-dom-shadow-css-tldr-4cgh