Web Components、Shadow DOM、Shadow CSS;tldr
我不会告诉你你应该立刻投入到 Web Components 中,也不会告诉你它是会取代你现有框架的全新酷炫玩意儿。
我正在尝试尽可能高效地解答以下问题,以便您更好地理解:
- 什么是 Web 组件?
- 什么是 Shadow DOM?
- 什么是插槽(以及什么是LightDOM)?
- 使用 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>
它们不会自动关闭,所以不要这样做!
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';
}
}
首先,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://developer.mozilla.org/en-US/docs/Web/CSS/::slotted
- https://developer.mozilla.org/en-US/docs/Web/CSS/:host()
- https://developer.mozilla.org/en-US/docs/Web/CSS/:host-context()