Shadow Dom

Shadow DOM 是一种 Web 标准,它允许开发者在主文档的 DOM 中嵌入一个隔离的 DOM 子树,这个子树有自己的元素、样式和脚本,而不会影响主文档。Shadow DOM 的主要作用是封装,可以使得组件的内部结构、样式和行为被隐藏和隔离起来,从而使得组件更加模块化和可复用。

Shadow DOM 的用法

创建一个带有 Shadow DOM 的元素

要创建一个 Shadow DOM,你需要选择一个普通的 DOM 元素并为其调用 attachShadow 方法。mode 选项可以设置为 openclosed,表示是否允许外部 JavaScript 访问 Shadow DOM。

ini 复制代码
// 创建一个新的 div 元素
const shadowHost = document.createElement('div');

// 将这个 div 元素添加到页面中
document.body.appendChild(shadowHost);

// 为这个 div 元素创建一个 Shadow DOM
const shadowRoot = shadowHost.attachShadow({ mode: 'open' });

向 Shadow DOM 添加内容

一旦你创建了 Shadow DOM,就可以通过 shadowRoot 添加内容,就像你在普通 DOM 中做的那样。

xml 复制代码
// 向 Shadow DOM 添加一些 HTML
shadowRoot.innerHTML = `
  <style>
    p { color: red; }
  </style>
  <p>Hello from Shadow DOM!</p>
`;

使用 <template><slot>

你可以使用 <template><slot> 标签来定义可重用的模板和插槽,这样你就可以将内容投影到 Shadow DOM 中。

xml 复制代码
<template id="my-template">
  <style>
    :host { display: block; }
    p { color: blue; }
  </style>
  <p><slot name="message">Default message</slot></p>
</template>

<script>
  customElements.define('my-element', class extends HTMLElement {
    constructor() {
      super();
      const template = document.getElementById('my-template');
      const templateContent = template.content;
      this.attachShadow({mode: 'open'}).appendChild(templateContent.cloneNode(true));
    }
  });
</script>

然后你可以像这样使用自定义元素:

xml 复制代码
<my-element>
  <span slot="message">Custom message</span>
</my-element>

当前广泛使用的场景

  1. Web Components: Shadow DOM 是 Web Components 规范的重要部分,允许创建封装好的自定义元素。
  2. 组件库: 诸如 Polymer、LitElement 和 Stencil 这样的库和框架使用 Shadow DOM 来创建封装的组件。
  3. 框架和工具: 某些现代前端框架,如 Angular 的元素封装策略也是利用了 Shadow DOM 的特性。

使用注意事项

  1. 兼容性: 并非所有浏览器都支持 Shadow DOM,尽管现代浏览器都已有较好的支持,但是应该通过特性检测或者 polyfill 来确保兼容性。
  2. 封装: Shadow DOM 的封装可能会导致样式和脚本不再像在全局 DOM 中那样容易被覆盖或修改,可能需要使用 :host::slotted() 伪元素进行样式穿透。
  3. 选择器: 由于封装,外部 CSS 选择器和 JavaScript querySelector 方法无法穿透 Shadow DOM 边界。
  4. 性能: Shadow DOM 的使用可能会带来额外的性能开销,因为它增加了额外的作用域和封装层。
  5. 工具和调试: 对 Shadow DOM 的调试和工具支持可能不如普通 DOM,特别是在一些旧的开发工具或环境中。
相关推荐
卓码软件测评几秒前
【第三方网站运行环境测试:服务器配置(如Nginx/Apache)的WEB安全测试重点】
运维·服务器·前端·网络协议·nginx·web安全·apache
龙在天2 分钟前
前端不求人系列 之 一条命令自动部署项目
前端
开开心心就好2 分钟前
PDF转长图工具,一键多页转图片
java·服务器·前端·数据库·人工智能·pdf·推荐算法
国家不保护废物8 分钟前
10万条数据插入页面:从性能优化到虚拟列表的终极方案
前端·面试·性能优化
文心快码BaiduComate23 分钟前
七夕,画个动态星空送给Ta
前端·后端·程序员
web前端12327 分钟前
# 多行文本溢出实现方法
前端·javascript
文心快码BaiduComate27 分钟前
早期人类奴役AI实录:用Comate Zulu 10min做一款Chrome插件
前端·后端·程序员
人间观察员29 分钟前
如何在 Vue 项目的 template 中使用 JSX
前端·javascript·vue.js
布列瑟农的星空32 分钟前
大话设计模式——多应用实例下的IOC隔离
前端·后端·架构
EndingCoder37 分钟前
安装与环境搭建:准备你的 Electron 开发环境
前端·javascript·electron·前端框架