Shadow DOM:Web 组件的封装与控制

技术 · 06-23 · 访问: 370 次
Shadow DOM:Web 组件的封装与控制

介绍

Shadow DOM 是 Web 组件规范的一部分,它允许将封装的“影子” DOM 树附加到常规 DOM 树中的元素。影子 DOM 封装了 DOM 和样式,使开发人员可以控制这些元素,而不会与页面上的其他代码或样式发生冲突。

术语

  • 影子宿主(Shadow host):影子 DOM 附加到的常规 DOM 节点。
  • 影子树(Shadow tree):影子 DOM 内部的 DOM 树。
  • 影子边界(Shadow boundary):影子 DOM 终止,常规 DOM 开始的地方。
  • 影子根(Shadow root):影子树的根节点。

shadowdom.png

创建 Shadow DOM

const host = document.querySelector('#host')
// 创建一个 Shandow DOM 元素
const shadow = host.attachShadow({mode: 'open'})

const span = document.createElement('span')
span.textContent = 'Hello World'

// 向 Shadow DOM 元素内填充内容
shadow.appendChild(span)

Shadow DOM 无法通过寻常方式来对里面的元素进行操作。

mode 选项

  • open:Shadow DOM 元素及其内容是可被 JavaScript 访问的,可以通过影子宿主的 shadowRoot 属性访问影子 DOM 的内部。
  • closed:Shadow DOM 元素及其内容是封闭的,无法被 JavaScript 访问。

访问 Shadow DOM 元素

通过 host.shadowRoot 方式来访问内部的 Shadow DOM 元素。

const host = document.querySelector('#host')
const shadow = host.attachShadow({ mode: "open" });
...

// 获取 Shadow DOM 元素
host.shadowRoot.querySelector('span')

css 样式

页面上的 css 样式不会影响到 Shadow DOM 元素,反之亦然。

想要在 Shadow DOM 元素上应用样式,有两种方式:

  • 编程式,通过构建一个 CSSStyleSheet 对象并将其附加达到影子根。
  • 声明式,通过在一个 template 元素的声明中添加一个 style 元素。

编程式

// 创建一个 CSSStyleSheet 对象
const sheet = new CSSStyleSheet();
sheet.replaceSync('span {color: red; border: 2px dotted black;}');

const host = document.querySelector('#host');
const shadow = host.attachShadow({mode: 'open'})

// 将样式表对象附加到影子根
shadow.adoptedStyleSheets = [sheet]

声明式

通过在 template 元素中添加一个 style 元素,然后将其附加到影子根。

<template id="my-element">
  <style>
    span {color: red; border: 2px dotted black;}
  </style>
  <span>Hello World</span>
</template>

<div id="host"></div>
// 获取 template 元素
const template = document.querySelector('#my-element')

const host = document.querySelector('#host')
const shadow = host.attachShadow({mode: 'open'})

// 将 template 元素的内容附加到影子根
shadow.appendChild(template.content);

自定义组件

通过 Shadow DOM 能够自定义组件,配合 customElemets.define() 来创建自定义组件。

详情

影子 DOM 和自定义元素

参考

前端 javascript javascript api 自定义组件 shadow dom
icon_mrgreen.gificon_neutral.gificon_twisted.gificon_arrow.gificon_eek.gificon_smile.gificon_confused.gificon_cool.gificon_evil.gificon_biggrin.gificon_idea.gificon_redface.gificon_razz.gificon_rolleyes.gificon_wink.gificon_cry.gificon_surprised.gificon_lol.gificon_mad.gificon_sad.gificon_exclaim.gificon_question.gif
Theme Jasmine by Kent Liao