Web Components 是现代 Web 开发中一个备受关注的技术,它提供了一种将页面分解成组件的方式,并可以复用这些组件。其中,Shadow Dom 是 Web Components 的核心特性之一,它为组件提供了一套独立、封闭的 DOM 树,实现了组件和页面的隔离。
Shadow Dom 的基本概念和实现
Shadow Dom(阴影 DOM)就是一种独立的 DOM 树,它位于组件内部与外部 DOM 树并列,但彼此独立。组件内部的节点只能被组件内部的 JavaScript 访问,不会影响到外部的 JavaScript。这样,一个组件就可以全部自我管理,不需要担心外部的样式和 JavaScript 会影响它的行为。
实现 Shadow Dom 很简单,只需要使用 shadowRoot
属性,在组件内部创建一个 DOM 树即可。
-- -------------------- ---- ------- --------- ------------------ ------- -- ------ -- -------- ---- ------------- ---- ------ --- ------ ----------- -------- ----- ----------- ------- ----------- - ------------- - -------- ----- ------ - ------------------- ----- ------ --- ----- -------- - ---------------------------------------- ----- ------- - --------------------------------- ---------------------------- - - ------------------------------------- ------------- ---------展开代码
在上面的代码中,我定义了一个 MyComponent
组件,并使用了 attachShadow
方法创建了 Shadow Dom。它的 mode
参数可以是 'open'
或者 'closed'
,前者表示外部 DOM 树可以访问 Shadow Dom,后者表示不能访问。
Shadow Dom 的样式隔离
Shadow Dom 可以保证组件内部的样式与外部的样式不会相互干扰。通常,我们会为组件的 Shadow Dom 容器添加一个 class 名称,以便于在样式中选择这个容器。
.my-component .root { color: red; }
Shadow Dom 的事件隔离
在 Shadow Dom 中,事件只能被组件内部的 JavaScript 处理,从而避免了不必要的事件处理以及可能引起的冲突和性能问题。相应地,使用 Shadow Dom 时需要注意事件的绑定和代理。
-- -------------------- ---- ------- --------- ------------------ ---- ------------- ------- ------------------------ ------ ----------- -------- ----- ----------- ------- ----------- - ------------- - -------- ----- ------ - ------------------- ----- ------ --- ----- -------- - ---------------------------------------- ----- ------- - --------------------------------- ---------------------------- - ------------------- - ----- ------ - -------------------------------------- -------------------------------- - -- - -------------- --- - - ------------------------------------- ------------- ---------展开代码
上面的代码中,我监听了 MyComponent
组件内部的一个按钮点击事件,但这个事件可以保证不会被外部代码监听。
Shadow Dom 的插槽
Web Components 的最大优势是组件化,而 Shadow Dom 的表现力与可重用性则需要依赖插槽(slot)的支持。插槽是 Shadow Dom 中表示组件内容占位符的组件部件,用于在组件与外部 DOM 文档之间传递内容。
-- -------------------- ---- ------- --------- ------------------ ---- ------------- ---------------- ------------- ------ ----------- -------------- --------------- ---------------展开代码
上面的代码中,我定义了一个 MyComponent
组件,并在组件内部使用了一个插槽。在使用组件时,我可以在组件标签中添加任意内容,这些内容将被显示在插槽位置上。
Shadow Dom 的插槽很灵活,它可以接受任何类型的 DOM 元素,还支持多个插槽和具名插槽。
Shadow Dom 的运用场景
Shadow Dom 可以帮助我们更好地封装和隔离组件内部的结构和行为,适用于一些需要高度独立、封闭的元素和组件。比如:
- 自定义表单控件
- 自定义弹窗组件
- 自定义图表组件
除此之外,Shadow Dom 还可以与其他 Web 技术一起使用,比如:
- 自定义元素(Custom Elements):可将 Shadow Dom 内容封装到一个自定义元素中,让其在多个组件中重复使用。
- Web Components 规范:Shadow Dom 是 Web Components 的一部分,与 Custom Elements、Templates、HTML Import 等规范一起构成了 Web Components 的核心 API。
总而言之,Shadow Dom 是一个非常有用的技术,可以帮助我们更好地实现组件化和模块化开发,提高代码质量和可维护性,是现代 Web 开发中不可或缺的一部分。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/67bea96c0c976d473a2c32a0