如何创建从HTMLButtonElement扩展的HyperHTML自定义元素

Jo *_*VdB 1 hyperhtml

我想有一个语义命名的自定义元素,从按钮扩展:喜欢 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

And*_*chi 5

很难回答这个问题,因为很难理解从哪里开始.

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 DOMaddEventListener,但没有别的,真的.

创建元素时,尚未升级.事实上,它很可能不会升级.

每个浏览器至少存在2个错误,以及3个关于自定义元素初始化的不一致行为,但最好的办法是,一旦connectedCallback调用,您确实拥有自定义元素节点内容.

connectedCallback() {
  this.slots = [...this.childNodes];
  this.render();
}
Run Code Online (Sandbox Code Playgroud)

通过这种方式,您确信实际上在DOM上实时呈现组件,而不是在没有内容时.

我希望我已经以一种方式回答了你的问题,这也警告你如果这是新项目的开始就不要使用内置的自定义元素:遗憾的是,对于你的应用程序的未来,它们不是一个安全的选择.

最好的祝福.