Blogger Information
Blog 91
fans 0
comment 0
visits 77274
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
Web Components 系列(二)—— 关于 Custom Elements
编程三昧
Original
772 people have browsed it

CustomElements.001

前言

在上一篇文章中介绍了 Web Components 的相关概念,知道它是浏览器用来原生支持“组件化”的方法,并且知晓它的技术组成为:

  • Custom Elements
  • Shadow DOM
  • HTML templates

今天,我们就来学习它的技术之一——Custom Element 的部分相关知识。

Custom Elements 的意义

Web Components 标准非常重要的一个特性是,它使开发者能够将 HTML 页面的功能封装为 custom elements(自定义标签),而往常,开发者不得不写一大堆冗长、深层嵌套的标签来实现同样的页面功能。

Custom Elements 是网页组件化的基础,也是其核心。

Custom Elements 的分类

根据是否继承基础 HTML 元素,将 Custom Elements 分为两类。

Autonomous custom elements

是独立的元素,它不继承其他内建的 HTML 元素。你可以直接把它们写成HTML标签的形式,来在页面上使用。例如 <my-card>,或者是document.createElement("my-card")这样。

Customized built-in elements

继承自基本的HTML元素。在创建时,你必须指定所需扩展的元素,使用时,需要先写出基本的元素标签,并通过 is 属性指定custom element的名称。例如<p is="my-card">, 或者 document.createElement("p", { is: "my-card" })

CustomElementRegistry 对象

我们对自定义标签的概念等相关知识已有了解,那在实际开发中到底怎么使用自定义标签呢?这里就需要介绍一下 Custom Elements 的重点对象——CustomElementRegistry 对象。

要获取它的实例,请使用 window.customElements 属性。它的主要作用有:

  • 给页面注册一个自定义标签
  • 获取已注册的 Custom Elements 的相关信息

我们来看一下 CustomElementRegistry 对象的相关方法:

image-20220207214934295

可以看到, CustomElementRegistry 对象包含四个方法:

  • CustomElementRegistry.define()
  • CustomElementRegistry.get()
  • CustomElementRegistry.upgrade()
  • CustomElementRegistry.whenDefined()

接下来,我们分别介绍一下 CustomElementRegistry 对象的各个方法。

CustomElementRegistry.define()

它被用来定义(创建)一个自定义标签。语法如下:

  1. customElements.define(name, constructor, options);

参数解析:

  • name 自定义标签名。注意:它不能是单个单词,且其中必须要有短横线,比如:my-card 这样的。
  • constructor 自定义元素构造器,它可以控制元素的表现形式、行为和生命周期等。
  • options 一个包含 extends 属性的配置对象,是可选参数。它指定了所创建的元素继承自哪个内置元素,可以继承任何内置元素。

返回值为 undefined。

使用示例:

  1. // 声明自定义标签构造函数类
  2. class MyCard extends HTMLParagraphElement{
  3. constructor(){
  4. super();
  5. ……
  6. }
  7. }
  8. // 注册自定义标签
  9. customElements.define('my-card', MyCard, { extends: 'p' });

CustomElementRegistry.get()

该方法用于返回之前定义的自定义标签的构造函数。语法如下:

  1. constructor = customElements.get(name);

name 表示想要获取的自定义标签构造函数的标签名,其格式也应该为短横线连接的单词。

指定名字的自定义元素的构造函数,如果没有使用该名称的自定义元素定义,则为undefined

使用示例:

  1. // 调用 get 方法
  2. customElements.get("my-card");
  3. // class MyCard extends HTMLParagraphElement{
  4. // constructor(){
  5. // super();
  6. // }
  7. // }
  8. customElements.get("MyCard");
  9. // undefined

CustomElementRegistry.upgrade()

该方法将更新 root 子树中所有包含影子 DOM 的自定义元素,甚至在它们载入主文档之前也可以更新。语法如下:

  1. customElements.upgrade(root);

root 表示带有要升级的包含阴影的后代元素的Node实例。如果没有可以升级的后代元素,则不会抛出错误。

其返回值为 undefined。

不调用 upgrade 方法:

  1. const el = document.createElement("my-card");
  2. class MyCard extends HTMLElement {}
  3. customElements.define("my-card", MyCard);
  4. console.log(el instanceof MyCard); // false

调用 upgrade 方法:

  1. const el = document.createElement("my-card");
  2. class MyCard extends HTMLElement {}
  3. customElements.define("my-card", MyCard);
  4. customElements.upgrade(el);
  5. console.log(el instanceof MyCard); // true

CustomElementRegistry.whenDefined()

返回当使用给定名称定义自定义元素时将会执行的 promise。如果已经定义了这样一个自定义元素,那么立即执行返回的 promise。语法如下:

  1. Promise<> customElements.whenDefined(name);

name 还是表示自定义标签的名称。

示例一:

  1. class MyCard extends HTMLParagraphElement {
  2. constructor() {
  3. super();
  4. }
  5. }
  6. customElements.whenDefined("my-card").then(() => {
  7. console.log(`my-card 被注册`);
  8. });
  9. console.log("my-card 注册前");
  10. customElements.define("my-card", MyCard, { extends: "p" });
  11. console.log("my-card 注册后");
  12. // my-card 注册前
  13. // my-card 注册后
  14. // my-card 被注册

如果再次执行以下代码,则会立即执行 resolve 方法:

  1. customElements.whenDefined("my-card").then((res) => {
  2. console.log(res);
  3. console.log(`my-card 被注册`);
  4. });
  5. // my-card 被注册

总结

以上就是关于 Custom Elements 的部分知识点,后续会补充自定义标签的生命周期函数等内容。

~

~ 本文完,感谢阅读!

~

学习有趣的知识,结识有趣的朋友,塑造有趣的灵魂!

大家好,我是〖编程三昧〗的作者 隐逸王,我的公众号是『编程三昧』,欢迎关注,希望大家多多指教!

Statement of this Website
The copyright of this blog article belongs to the blogger. Please specify the address when reprinting! If there is any infringement or violation of the law, please contact admin@php.cn Report processing!
All comments Speak rationally on civilized internet, please comply with News Comment Service Agreement
0 comments
Author's latest blog post