WebComponent

Web Component

作为开发者,我们都知道尽可能多的重用代码是一个好主意。这对于自定义标记结构来说通常不是那么容易 — 想想复杂的HTML(以及相关的样式和脚本),有时您不得不写代码来呈现自定义UI控件,并且如果您不小心的话,多次使用它们会使您的页面变得一团糟。

Web Components旨在解决这些问题 — 它由三项主要技术组成,它们可以一起使用来创建封装功能的定制元素,可以在你喜欢的任何地方重用,不必担心代码冲突。

  • Custom elements(自定义元素): 一组javaScript API,允许定义custom elements以及行为。
  • Shadow DOM(影子DOM):一组JavaScript API,用于将封装的“影子”DOM树附加到元素(与主文档DOM分开呈现)并控制其关联的功能。通过这种方式,您可以保持元素的功能私有,这样它们就可以被脚本化和样式化,而不用担心与文档的其他部分发生冲突。
  • HTML templates(HTML模板):====和 ====元素使您可以编写不在呈现页面中显示的标记模板。然后它们可以作为自定义元素结构的基础被多次重用。

实现web component的基本方法:

  1. 创建一个类或函数来指定web组件的功能,如果使用类,请使用 ECMAScript 2015 的类语法(参阅获取更多信息)。
  2. 使用 CustomElementRegistry.define() 方法注册您的新自定义元素 ,并向其传递要定义的元素名称、指定元素功能的类、以及可选的其所继承自的元素。
  3. 如果需要的话,使用Element.attachShadow() 方法将一个shadow DOM附加到自定义元素上。使用通常的DOM方法向shadow DOM中添加子元素、事件监听器等等。
  4. 如果需要的话,使用 ](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/template) 和[`` 定义一个HTML模板。再次使用常规DOM方法克隆模板并将其附加到您的shadow DOM中。
  5. 在页面任何您喜欢的位置使用自定义元素,就像使用常规HTML元素那样。

一、自定义元素

custom elements(自定义标签)

CustomElementRegistry 接口的实例用来处理 web 文档中的 custom elements — 该对象允许你注册一个 custom element,返回已注册 custom elements 的信息,等等。

CustomElementRegistry.define() 方法用来注册一个 custom elemen(自定义组件)

customElements.define('word-count', WordCount, { extends: 'p' });
  • 参数一:自定义的标签名字,中间必须有短线
  • 参数二:用于定义元素行为的类
  • 参数三(可选):指定继承哪个内置元素。(任何的)
class WordCount extends HTMLParagraphElement {
  constructor() {
    // 必须首先调用 super 方法
    super();

    // 元素的功能代码写在这里
    // 1. 创建一个 shadow root ,mode值 open/closed,隐藏元素
    var shadow = this.attachShadow({mode: 'closed'});
    // 2.创建元素节点,并设置类名
    var wrapper = document.createElement('span');
	wrapper.setAttribute('class','wrapper');
    var info = document.createElement('span');
	info.setAttribute('class','info');
    // 3.设置属性,定义在customDom上面的属性
    var text = this.getAttribute('text');
	info.textContent = text;
    // 4.创建css样式
    var style = document.createElement('style');
    style.textContent = ``;
    // 5.将创建的元素附加到 shadow dom
    shadow.appendChild(style);
	shadow.appendChild(wrapper);
    wrapper.appendChild(info);
    ...
  }
}
// 注册自定义组件
window.customElements.define("custom-elem",WordCount);

constructor()函数里面可以设定一些生命周期的回调函数,特定时间,回调函数自动被调用

connectedCallback() : 元素首次被插入到文档DOM节点上时被调用。

attributeChangedCallback() : 元素增加、删除或者修改某个属性时被调用。

二、Shadow DOM(隐藏元素)

作用:用于封装组件元素的内部细节,向外提供属性注入,可以将标记结构、样式和行为隐藏起来,并与页面上的其他代码相隔离,保证不同的部分不会混在一起,可使代码更加干净、整洁。可以将一个隐藏的、独立的 DOM 附加到一个元素上

img

相关术语:

  • Shadow host:一个常规 DOM节点,Shadow DOM 会被附加到这个节点上。
  • Shadow tree:Shadow DOM内部的DOM树。
  • Shadow boundary:Shadow DOM结束的地方,也是常规 DOM开始的地方。
  • Shadow root: Shadow tree的根节点。

用法

Element.attachShadow()方法创建一个 shadow root,将创建的元素附加到 shadow dom,

有一个mode属性,值可以为open或者closed;

let shadow = elementRef.attachShadow({mode: 'open'});
let shadow = elementRef.attachShadow({mode: 'closed'});
  • open 表示可以通过页面内的 JavaScript 方法来获取 Shadow DOM

    let myShadowDom = myCustomElem.shadowRoot;
    
  • closed表示不可以从外部获取 Shadow DOM 了——myCustomElem.shadowRoot 将会返回 null

三、使用模板(Templates)

当必须在网页上重复使用相同的标记结构时,可以使用模板(template),使用HTML 的====元素实现,此元素及其内容不会在DOM中呈现,但仍可使用JavaScript去引用它。

定义一个template: (此代码在html中插入,但不会显示在页面当中,只有通过js引用的时候才会显示)

<template id="my-template">
   <style>
       p {
           color: white;
           background-color: #666;
           padding: 5px;
       }
  </style>
  <p>My Template</p>
</template>

通过js引用到dom中:

let template = document.getElementById('my-template');
let templateContent = template.content;
document.body.appendChild(templateContent);

*与 web Component一起使用: (模板与自定义组件的结合)

customElements.define('my-template',
  class extends HTMLElement {
    constructor() {
      super();
      let template = document.getElementById('my-paragraph');
      let templateContent = template.content;
		
      const shadowRoot = this.attachShadow({mode: 'open'})
        .appendChild(templateContent.cloneNode(true));
       // templateContent.cloneNode(true)将模板拷贝到shadowRoot的根结点上
  }
})

使用插槽:(在模板中定义插槽的位置,然后在自定义标签中指定slot的属性值,可以继承插槽所在的标签样式以及内容)

<!-- 使用模板 -->
<text-template>
    <!-- 使用插槽 -->
    <span slot="my-text"></span>
</text-template>
<!-- 定义模板 -->
<template id="my-template">
    <style type="text/css">
        p {
            color: blueviolet;
            font-size: 16px;
            padding: 5px;
        }
    </style>
    <p>
        <slot name="my-text">My default text</slot>
        hhhhh
    </p>
</template>

> 相关链接:https://developer.mozilla.org/zh-CN/docs/Web/Web_Components
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值