Custom Elements 和 Shadow DOM 结合实现可复用、样式隔离的 Web 组件:通过定义类继承 HTMLElement 并注册自定义标签,结合 attachShadow 创建独立 DOM 子树,利用 slot 分发内容,实现结构与样式的完全封装,支持属性监听与动态渲染,构建原生 JavaScript 组件。

Custom Elements 和 Shadow DOM 是 Web Components 的两个核心部分,它们让开发者可以创建可复用、封装良好的自定义 HTML 元素。结合使用,能够构建真正独立、样式隔离、行为清晰的组件,直接在原生 JavaScript 中实现类似框架的功能。
Custom Elements:定义自己的 HTML 标签
Custom Elements 允许你创建新的 HTML 标签,并为其定义对应的行为。通过 customElements.define() 方法注册一个类,这个类继承自 HTMLElement 或其子类,就可以在页面中使用自定义标签。
基本步骤如下:
- 定义一个类,继承自 HTMLElement
- 在类中使用 constructor 初始化元素(必须调用 super())
- 通过 connectedCallback 在元素插入 DOM 时执行逻辑
- 可选地使用 attributeChangedCallback 监听属性变化
- 调用 customElements.define('my-element', MyElement) 注册组件
示例:
立即学习“Java免费学习笔记(深入)”;
class MyCard extends HTMLElement {
constructor() {
super();
this.attachShadow({ mode: 'open' });
}
connectedCallback() {
const title = this.getAttribute('title') || '默认标题';
this.shadowRoot.innerHTML = `
${title}
`;
}
}
customElements.define('my-card', MyCard);
使用方式:
这里是内容
Shadow DOM:实现真正的样式和结构封装
Shadow DOM 提供了一个独立的 DOM 子树,它与主文档 DOM 隔离,包括样式和事件。这意味着你在 Shadow Root 中定义的 CSS 不会影响外部页面,外部样式也不会轻易“穿透”进来。
关键特性:
- 通过 this.attachShadow({ mode: 'open' }) 创建 Shadow Root
- mode 可为 'open'(可通过 JS 访问)或 'closed'(不可访问)
- 所有内部结构和样式都挂载到 shadowRoot 上
- 支持
实现内容分发,保留原有 HTML 内容的灵活性
Shadow DOM 的优势在于:
- 样式隔离:组件内样式不会污染全局
- 结构隐藏:内部实现细节对外不可见
- 避免选择器冲突:即使使用 .title 这样的通用类名也不怕
示例说明 slot 用法:
this.shadowRoot.innerHTML = ``;默认内容
对应使用:
这是头部 这是主体内容
结合使用:构建完整 Web 组件
Custom Elements 负责定义标签和行为,Shadow DOM 负责封装 UI 和样式,两者结合是 Web Components 的标准实践。
常见模式包括:
- 在 constructor 中 attachShadow 并初始化内部结构
- 在 connectedCallback 中渲染或绑定事件
- 监听 attributes 列表并通过 observedAttributes 静态属性指定需要监控的属性
- 使用 attributeChangedCallback 响应属性更新
增强示例:响应属性变化
class MyToggle extends HTMLElement {
static get observedAttributes() {
return ['on'];
}
constructor() {
super();
this.attachShadow({ mode: 'open' });
}
connectedCallback() {
this.render();
}
attributeChangedCallback(name, oldValue, newValue) {
if (name === 'on') {
this.render();
}
}
render() {
const isOn = this.getAttribute('on') === 'true';
this.shadowRoot.innerHTML = `
`;
}
}
customElements.define('my-toggle', MyToggle);
使用:
基本上就这些。掌握 Custom Elements 和 Shadow DOM,就能写出不依赖框架、原生支持、可跨项目复用的组件。虽然没有 React 或 Vue 那样丰富的生态,但在轻量级封装、微前端集成、设计系统建设中非常有价值。










