创建
创建 custom element 是 Web components 一个关键的功能。custom element 跟我们常用内建标签(如 <div>
、<span>
)都是 HTML 元素,只不过 custom element 的行为由开发者自己定义。
custom element 的定义通过类来实现,这个类继承自 HTMLElement
或者内建的 HTML 元素。如果 custom element 继承自 HTMLElement
,则元素的所有功能都需要开发者重新实现。下面的例子展示了一个继承自 HTMLElement
的 custom element 的定义:
class MyCustomElement extends HTMLElement {
constructor() {
super();
}
// 在此处编写自定义元素的功能
}
在 class 的 constructor 中,我们可以设置初始化状态以及默认值,注册事件监听器,创建 shadow DOM 等。但需要注意的是,在 constructor 中不能访问元素的属性以及子元素,因为在实例化的时候,custom element 还没有添加到文档中。
生命周期回调
Custom element 包含几个生命周期回调:
connectedCallback()
:每当元素被添加到文档的时候被调用。disconnectedCallback()
:每当元素从文档中移除的时候被调用。adoptedCallback()
:每当元素被移动到新的文档的时候被调用。attributeChangedCallback()
:每当元素的一个属性被增加、移除或者更改的时候被调用。
下面是 custom element 包含生命周期回调的最小实现:
class MyCustomElement extends HTMLElement {
static observedAttributes = ["color", "size"];
constructor() {
super();
}
connectedCallback() {
console.log("Custom element added to page.");
}
disconnectedCallback() {
console.log("Custom element removed from page.");
}
adoptedCallback() {
console.log("Custom element moved to new page.");
}
attributeChangedCallback(name, oldValue, newValue) {
console.log(`Attribute ${name} has changed.`);
}
}
customElements.define("my-custom-element", MyCustomElement);
响应属性变化
与内建元素类似,自定义元素能够使用 HTML 属性来控制元素的行为。为了更有效地利用 HTML 属性,需要自定义元素有能够响应 HTML 属性变化的能力,而要实现这个能力,则需要在 custom element 中声明静态属性 observedAttributes
以及实现生命周期回调 attributeChangedCallback()
。
attributeChangedCallback
的值为数组,包含所有需要监听变化的属性名。而 attributeChangedCallback
生命周期回调接受参数,第一个参数位属性名,第二个参数为属性变化前的值,第三个参数位属性变化后的值。
下面是实现相应属性变化的简单例子:
class MyCustomElement extends HTMLElement {
static observedAttributes = ["size"];
constructor() {
super();
}
attributeChangedCallback(name, oldValue, newValue) {
console.log(`Attribute ${name} has changed from ${oldValue} to ${newValue}.`);
}
}
customElements.define("my-custom-element", MyCustomElement);
注册与使用
为了使得 custom element 可以在页面上正常使用,需要通过 Window.customElements
对象的 define()
方法对 customer element 进行注册。define()
方法接收三个参数:
name
:自定义元素的名称,必须包含一个短横线,比如my-custom-element
。constructor
:自定义元素的构造函数options
:仅在 custom element 继承自内建元素的时候使用。该对象仅包含extends
属性,值为扩展的内建元素的名称。
customElements.define("my-custom-element", MyCustomElement);
当定义和注册了 custom element 之后,就可以在页面上使用了。
<my-custom-element></my-custom-element>