Skip to content
导航

Web Components

Web Components 用于创建可重用的自定义元素,由三项主要技术组成:

  • shadow DOM
  • Custom element
  • template and slot

Shadow DOM

Shadow DOM 可以将标记结构、样式和行为隐藏起来,并与页面上的其他代码相隔离。
Shadow DOM 内部的元素始终不会影响到它外部的元素(除了 :focus-within

用法

html
<div id="app"></div>
<script>
const shadow = document.querySelector('#app').attachShadow({ mode: 'open' })
shadow.appendChild(document.createTextNode('Shadow DOM'))
</script>

Element.attachShadow({ mode, delegatesFocus })方法将一个 shadow root 附加到任何元素上,返回对shadowRoot的引用。

  • mode参数值可以是:
    • open: 表示可以通过 Element.shadowRoot 获取 Shadow DOM
    • closed:表示不可以通过 Element.shadowRoot 获取 Shadow DOM,Element.shadowRoot = null
  • delegatesFocus:Boolean
    • 当 shadow DOM 中不可聚焦的部分被点击时,让第一个可聚焦的部分成为焦点,并且 shadow host 将提供所有可用的 :focus 样式。

Custom element

使用window.customElements.define()注册自定义元素:

js
customElements.define(
  'extend-p',
  class extends HTMLParagraphElement {
    constructor(){
      // 必须首先调用 super 方法
      super()
      // 元素的功能代码...
    }
  },
  { extends: 'p' },
)

共有两种 custom elements:

  • Autonomous custom elements 是独立的元素,它不继承其他内建的 HTML 元素。可以直接在页面上使用标签,例如<custom-p>
  • Customized built-in elements 继承自基本的 HTML 元素。不能作为标签使用,通过 is 属性指定 custom element 的名称。例如<p is="extend-p">

在class中,支持使用生命周期回调函数:

  • connectedCallback:当 custom element 首次被插入文档 DOM 时,被调用。
  • disconnectedCallback:当 custom element 从文档 DOM 中删除时,被调用。
  • adoptedCallback:当 custom element 被移动到新的文档时,被调用。
  • attributeChangedCallback: 当 custom element 增加、删除、修改自身属性时,被调用。

DEMO - custom
DEMO源码 - custom

template and slot

template

<template>标签及其内容不会在 DOM 中呈现,可使用 JavaScript 去引用它。

简单示例:

html
<template id="my-paragraph">
  <p>My paragraph</p>
</template>
<script>
  let template = document.getElementById('my-paragraph');
  let templateContent = template.content;
  document.body.appendChild(templateContent);
</script>

slot

以下名词参考Vue.js

<slot>标签用于为<template>添加默认插槽。可以设置name属性,以添加具名插槽。

简单示例:

html
<template id="custom-element-template">
  <slot></slot>
  <slot name="named"></slot>
</template>

<custom-element>
  <p slot="named">这里会展示在具名插槽<</p>
  <p>这里会展示在默认插槽</p>
</custom-element>

DEMO - template and slot
DEMO源码 - template and slot

参考资料