要定义自定义Web组件,我们可以扩展ES6类以访问元素的生命周期反应。
class HelloElement extends HTMLElement {
// Monitor the 'name' attribute for changes.
static get observedAttributes() {return ['name']; }
// Respond to attribute changes.
attributeChangedCallback(attr, oldValue, newValue) {
if (attr == 'name') {
this.textContent = `Hello, ${newValue}`;
}
}
}
// Define the new element
customElements.define('hello-element', HelloElement);
ES5的等效方式是什么?
答案 0 :(得分:7)
根据您的评论,我认为您的意思是ES6 语法,并且允许支持自定义元素的浏览器也支持ES6定义的功能。
要模拟调用super()
的默认ES6构造函数,我们可以使用Reflect.construct
来调用HTMLElement
构造函数,但使用我们的HelloElement
遍历器中的原型。
对于继承,您需要将.prototype
构造函数的HelloElement
设置为HTMLElement
的实例,并在其上定义方法和属性。通常使用use Object.create()
来创建一个非功能性的虚拟实例,而不需要在这里调用构造函数。
您可以使用Object.defineProperty
为observedAttributes
定义静态getter,但它通常只是一个静态列表,您只需将HelloElement.observedAttributes
设置为属性名称数组即可。
function HelloElement() {
return Reflect.construct(HTMLElement, [], HelloElement);
}
HelloElement.prototype = Object.create(HTMLElement.prototype);
// Monitor the 'name' attribute for changes.
Object.defineProperty(HelloElement, 'observedAttributes', {
get: function() { return ['name']; }
});
// or just use HelloElement.observedAttributes = ['name']
// if it doesn't need to be dynamic
// Respond to attribute changes.
HelloElement.prototype.attributeChangedCallback = function(attr, oldValue, newValue) {
if (attr == 'name') {
this.textContent = `Hello, ${newValue}`;
}
}
customElements.define('hello-element', HelloElement);
setTimeout(function() {
document.getElementById('example').setAttribute('name', "World");
}, 1000);
<hello-element id="example"></hello-element>
答案 1 :(得分:1)
没有ES5编写Web组件类的方法。 Web components require ES6 features,没有办法解决这个问题。如果您不能使用ES6 class
语法,因为您的转换器没有发出,您至少需要使用ES6 Reflect.construct
来创建具有您自己的原型的自定义元素。
或者,custom elements polyfill appears to work with ES5 classes,至少在大多数浏览器中都是如此。
答案 2 :(得分:0)
对于ECMAScript 5而言,它并没有真正有效地工作,而对于DOM节点来说,它更低效。如果您愿意,可以添加到主机原型中,但是您不会得到一个实际的,干净的子类。
这就是有时将对象包装器用于DOM元素的原因。
答案 3 :(得分:0)
您可以使用Reflect
方法来执行此操作,但这是ES6的功能。
function CustomElement() {
return Reflect.construct(HTMLElement, [], CustomElement);
}
Object.setPrototypeOf(CustomElement.prototype, HTMLElement.prototype);
Object.setPrototypeOf(CustomElement, HTMLElement);
customElements.define('custom-element', CustomElement);
var elem = document.createElement('custom-element');
document.body.appendChild(elem);
这会将<custom-element></custom-element>
附加到body
。