Web Components之自定义HTML标签

一、Web Components

  Web Components是一种组件化的方式,它允许您创建可重用的定制元素(它们的功能封装在您的代码之外)并且在您的web应用中使用它们。Web Components的一个重要特性是封装,通过Web Components创建的组件,可以有效地将其自身的html结构、css样式及行为隐藏起来,并从页面中的其他代码分离出来,也就是每个组件都是独立的,不会互相干扰。下面是一个Web Components的简单应用:

<custom-button text="自定义按钮">custom-button>

在这里插入图片描述
  从上面可以看出我们通过自定义了一个custom-button标签,让按钮拥有了一些自定义的样式,可以看出这种方式其实就是组件化的思想。那么这样一个自定义标签如何实现的呢?

二、自定义标签

  W3C制定了两种custom elements: Autonomous custom elementsCustomized built-in elements

2.1 Autonomous custom elements

  独立的元素,这种元素不会继承现有内建的HTML标签。你可以通过document.createElement('custom-button')来进行使用。
  下面我们来实现上面的小例子,实现这样一个例子很简单,W3C提供了一个HTMLElement类,我们通过继承该类即可实现我们自定义的标签:

class CustomButton extends HTMLElement{
  constructor() {
    super()
    
    // 创建一个shadow root
    const shadow = this.attachShadow({mode: 'open'})
    
    // 创建一个button
    const button = document.createElement('button')
    button.setAttribute('class', 'custom-button')
    
    const text = this.getAttribute('text')
    button.textContent = text
    
    // 创建样式
    const style = document.createElement('style')
    style.textContent = `
      .custom-button{
        border: none;
        cursor: pointer;
        background: hsla(130, 70%, 50%, 1);
        color: #ffffff;
        line-height: 30px;
        border-radius: 5px;
      }
    `
    
    // 将创建的元素添加到shadow dom中
    shadow.appendChild(style)
    shadow.appendChild(button)
  }
  
}

// 注册自定义的标签
customElements.define('custom-button', CustomButton)

2.1.1 Shadow DOM

  可以看出上面代码在继承HTMLElement之后,我么执行了this.attachShadow({mode: 'open'}),该行是创建一个Shadow Dom,那么Shadow Dom是个什么东西呢?Shadow Dom是每个标签之间不会互相干扰的关键所在,它可以将一个隐藏的、独立的DOM添加到一个元素上。操作Shadow Dom与常规的Dom没有任何区别——例如添加子节点、设置属性,以及为节点添加自己的样式,或者为整个 Shadow DOM添加样式(例如在