继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

Web Components系列(三) —— 创建 Custom Elements

编程三昧
关注TA
已关注
手记 87
粉丝 28
获赞 84

浏览器数据库 IndexedDB.001

前言

根据前面的介绍,我们知道根据是否继承基本 HTML 元素,可以将自定义元素分为两类“

  • Autonomous custom elements 自主定制元素
  • Customized built-in elements 自定义内置元素

由此产生了一个疑问:这两者在使用上到底有何区别?

且让我通过本篇文章试着解释一下这个问题。

Autonomous custom elements

自主定制元素,是独立的元素,它不继承其他内建的 HTML 元素。

你可以直接把它们写成HTML标签的形式,来在页面上使用。例如 <my-card>,或者是document.createElement("my-card")这样。

示例

下面是一个创建和使用 Autonomous custom elements 的例子:

<!-- index.html -->
<body>
    <my-card></my-card>
    <script src="./index.js"></script>
</body>
// index.js
class MyCard extends HTMLElement {
    constructor() {
        super();
        let shadow = this.attachShadow({ mode: "open" });

        let containerEle = document.createElement("div");
        containerEle.style.display = "flex";
        containerEle.style.flexDirection = "column"
        containerEle.style.margin = "100px";
        containerEle.style.border = "1px solid #aaa";

        const headerEle = document.createElement("div");
        headerEle.innerText = "名片";
        headerEle.style.height = "20px";
        headerEle.style.padding = "10px";
        headerEle.style.borderBottom = "1px solid blue";

        const bodyEle = document.createElement("div");
        bodyEle.innerText = "姓名:编程三昧";
        bodyEle.style.padding = "10px";

        containerEle.appendChild(headerEle);
        containerEle.appendChild(bodyEle);
        shadow.appendChild(containerEle);
    }
}

customElements.define("my-card", MyCard);

其效果如下:

image-20220208211638861

打开开发者工具,查看 DOM 结构,如下图所示:

image-20220208212443770

尝试一

然后,我试着将注册接口传参改为 customElements.define("my-card", MyCard, {extends: "p"});,结果,页面不显示,也无任何报错信息。

尝试二

如果将 MyCard 类改为继承自 HTMLDivElement,即:

// index.js
class MyCard extends HTMLDivElement{
	constructor(){
		super();
		……
	}
}
……

页面有报错:

image-20220208214258852

尝试三

在自定义元素的构造器的结束部分加入以下代码:

this.style.display = "block";
this.style.border = "2px solid #aaa";

边框添加成功,这里要注意的是:继承自 HTMLElement 的样式 display 置为 inline,如果不重新设置 display 的值,那么样式效果会显示不出来。

Customized built-in elements

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

示例

下面是一个使用 Customized built-in elements 的例子:

<!--index.html-->

<body>
    <div is="my-card"></div>
    <script src="./index.js"></script>
</body>
// index.js

class MyCard extends HTMLDivElement {
    constructor() {
        super();
        let shadow = this.attachShadow({ mode: "open" });

        let containerEle = document.createElement("div");
        containerEle.style.display = "flex";
        containerEle.style.flexDirection = "column"
        containerEle.style.margin = "100px";
        containerEle.style.border = "1px solid #aaa";

        const headerEle = document.createElement("div");
        headerEle.innerText = "名片";
        headerEle.style.height = "20px";
        headerEle.style.padding = "10px";
        headerEle.style.borderBottom = "1px solid blue";

        const bodyEle = document.createElement("div");
        bodyEle.innerText = "姓名:编程三昧";
        bodyEle.style.padding = "10px";

        containerEle.appendChild(headerEle);
        containerEle.appendChild(bodyEle);
        shadow.appendChild(containerEle);
    }
}

customElements.define("my-card", MyCard, {extends: "div"});

效果跟 Autonomous custom elements 效果相同,其 DOM 结构如下:

image-20220208213737884

尝试一

如果在 index.html 中只使用 my-card 标签,则没有任何显示。

尝试二

如果将父类中的 HTMLDivElement 改为 HTMLElement,页面有报错:

image-20220208214645068

尝试三

如果去掉 customElements.define() 的第三个参数,则无报错也无页面显示。

总结

综合上述,可以总结如下:

  • Autonomous custom elements 的构造函数只能继承 HTMLElement,且调用 customElements.define() 方法时不需要第三个参数;
  • HTML 中直接使用 Autonomous custom elements 定义的标签名称即可;
  • Autonomous custom elements 样式的 display 值默认为 inline,如有需要,可重新设置;
  • Customized built-in elements 的构造函数一般只能继承可用的基本 HTML 标签类,且调用 customElements.define() 方法时必须要传入第三个参数,第三个参数一般为: {extends: "标签名"}
  • HTML 中直接使用 Customized built-in elements 时,需要通过组件构造函数继承类的基本标签名 + is="自定义标签名"
~
本文完,感谢阅读!

~

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

打开App,阅读手记
0人推荐
发表评论
随时随地看视频慕课网APP