我想有一个语义命名的自定义元素,从按钮扩展:喜欢 fab-button
class FabButton extends HTMLButtonElement {
constructor() {
super();
this.html = hyperHTML.bind(this);
}
}
customElements.define("fab-button", FabButton);
Run Code Online (Sandbox Code Playgroud)
扩展HTMLButtonElement似乎不起作用.
有没有办法从非HTMLElement扩展HyperHTML"document-register-element.js"?
Codepen示例:https://codepen.io/jovdb/pen/qoRare
很难回答这个问题,因为很难理解从哪里开始.
TL; DR解决方案虽然在这里,但它需要很多解释.
扩展内置插件是Web规范中的一个重点
无论WHATWG说什么都没关系,内置插件是事实上的死亡规范,因为Webkit强烈反对它,而Firefox,以及Edge,甚至从未发过自定义元素,也没有推动它们.
因此,作为起点,不鼓励使用Custom Elements V1规范扩展内置函数.
你可能会对V0好运,但那只是Chrome API,而且它已经是为了死而创建的那些API之一(RIP WebSQL).
我的polyfill按照定义遵循规范
文件寄存器元素polyfill与V0一起生成,但是用V1进行了改进,它遵循尽可能接近的规范,这就是为什么它可以扩展内置插件的原因,因为WHATWG仍然有这个部分.
这也意味着您需要了解扩展内置函数的工作原理.
它不是通过定义一个扩展的简单类来HTMLButtonElement获得一个按钮,而是需要至少做三件事:
// define via the whole signature
customElements.define(
"fab-button",
FabButton,
{extends: 'button'}
);
Run Code Online (Sandbox Code Playgroud)
...但也...... 让polyfill工作
// constructor might receive an instance
// and such instance is the upgraded one
constructor(...args) {
const self = super(...args);
self.html = hyperHTML.bind(self);
return self;
}
Run Code Online (Sandbox Code Playgroud)
而最重要的,在网页上的最基本的表现会是这样
<button is="fab-button">+</button>
Run Code Online (Sandbox Code Playgroud)
请记住,ES6类super(...args)总是会返回当前上下文.它是授予超级构造函数不返回其他实例作为升级对象.
构造函数不是你的朋友
由于恶劣因为它的声音,自定义元素的构造与只工作Shadow DOM和addEventListener,但没有别的,真的.
创建元素时,尚未升级.事实上,它很可能不会升级.
每个浏览器至少存在2个错误,以及3个关于自定义元素初始化的不一致行为,但最好的办法是,一旦connectedCallback调用,您确实拥有自定义元素节点内容.
connectedCallback() {
this.slots = [...this.childNodes];
this.render();
}
Run Code Online (Sandbox Code Playgroud)
通过这种方式,您确信实际上在DOM上实时呈现组件,而不是在没有内容时.
我希望我已经以一种方式回答了你的问题,这也警告你如果这是新项目的开始就不要使用内置的自定义元素:遗憾的是,对于你的应用程序的未来,它们不是一个安全的选择.
最好的祝福.