「这是我参与11月更文挑战的第3天,活动详情查看:2021最后一次更文挑战」。
Custom Element
自定义网页元素,叫做 custom element ,当 html 预定义的网页元素不满足需求时,就可以使用 custcom element。
特点
- 自定义网页元素的标签名必须含有连字符(-),一个或多个都可。这是因为浏览器内置的的HTML元素标签名,都不含有连字符,这样可以做到有效区分。
- 支持重写原型和 API 让自定义元素拥有特殊的属性,方法,和回调。普通的 HTML 元素,他的原型为
HTMLELement.prototype
,自定义元素可以自定义原型,在原型上挂载各种方法,已达到方便使用的目的。
document.registerElement()
- 使用自定义元素前,必须用document对象的registerElement方法登记该元素。该方法返回一个自定义元素的构造函数。
var SuperButton = document.registerElement('super-button');
document.body.appendChild(new SuperButton());
复制代码
我们发现自定义的元素实际是一个构造函数,调用后返回定义的元素节点,以供添加到页面中。
registerElement(eleName,eleProtoype)
接受两个参数,第一个参数是元素名称,第二个是该元素的原型。
var MyElement = document.registerElement('user-profile', {
prototype: Object.create(HTMLElement.prototype)
});
复制代码
我们看到上面例子中,我们原型指定的是HTMLElement.prototype
,这里的含义是指浏览器内部所有的Element 节点的原型,这样做的画,自定义元素就没有太大含义,自定义元素最大的优点就是可以自定义API
,可以定义新的属性和方法,可以注册回调函数。
创建拥有特殊原型的自定义元素
var buttonProto = Object.create(HTMLElement.prototype);
buttonProto.print = function() {
console.log('Super Button!');
}
var SuperButton = document.registerElement('super-button', {
prototype: buttonProto
});
var supperButton = document.querySelector('super-button');
supperButton.print();
复制代码
首先我们用Object.create
根据普通的元素原型创建一个原型模板,然后基于该对象进行改造,添加了一个print方法,然后我们再将该原型指定给我们的自定义元素super-button
,然后我们的自定义元素super-button
实例都可以调用 print 方法。
对于自定义元素的继承还可以使用 extends ,可以继承已有的元素属性,例如相让自定义元素继承 h1 元素的特征,可以用以下方法
var MyElement = document.registerElement('another-heading', {
prototype: Object.create(HTMLElement.prototype),
extends: 'h1'
});
复制代码
这样 MYElement 元素,就成了和 h1元素一样的特性了。
当然 extends 也可以继承自定义元素
自定义元素的使用
-
直接使用标签
-
使用某个现有标签,然后将其指定为自定义标签的实例
<!-- 直接使用 -->
<supper-button></supper-button>
<!-- 间接使用 -->
<button is="supper-button"></button>
复制代码
在自定义元素上添加属性和方法
上面说到,自定义元素相对普通元素的优点就是可以自定义元素上的属性和方法,我们看一下实际使用的案例
// 添加属性
Object.defineProperty(XFooProto, "bar", {value: 5});
// Object.defineProperty() 方法会直接在一个对象上定义一个新属性,
//或者修改一个对象的现有属性,并返回此对象。
//Object.defineProperty(obj, prop, descriptor)
// 参数:
//obj 要定义属性的对象。
//prop 要定义或修改的属性的名称或 Symbol 。
//descriptor 要定义或修改的属性描述符。
// 添加方法
XFooProto.foo = function() {
console.log('foo() called');
};
// 另一种写法
var XFoo = document.registerElement('x-foo', {
prototype: Object.create(HTMLElement.prototype, {
bar: {
get: function() { return 5; }
},
foo: {
value: function() {
console.log('foo() called');
}
}
})
});
XFoo.bar() //5
XFoo.foo() //foo() called
复制代码