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

How to create a HyperHTML custom element extended from HTMLButtonElement

我想要一个从按钮扩展的语义命名自定义元素:比如 fab-button

class FabButton extends HTMLButtonElement {
    constructor() {
        super();
        this.html = hyperHTML.bind(this);
    }
}
customElements.define("fab-button", FabButton);

HTMLButtonElement 的扩展似乎不起作用。

有没有办法使用 HyperHTML 从非 HTMLElement 扩展 "document-register-element.js"?

Codepen 示例: https://codepen.io/jovdb/pen/qoRare

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

尽管是 TL;DR 解决方案,is here,但它需要很多解释。

扩展 built-ins 是 Web 规范中的幽灵

WHATWG says、built-ins 是de-facto 死亡规范并不重要,因为 Webkit 强烈反对它,而 Firefox 和 Edge 甚至从未发布过 Custom元素,也没有强求。

因此,作为起点,不鼓励使用自定义元素 V1 规范扩展 built-ins。

虽然你可能对 V0 很幸运,但这只是 Chrome API,它已经是那些 API 中的一个了(R.I.P。WebSQL) .

我的 polyfill 按照定义遵循规范

document-register-element polyfill,在 V0 中诞生但在 V1 中进行了改进,尽可能地遵循规范,这就是为什么它可以扩展 built-ins,因为 WHATWG 仍然有那个部分。

这也意味着您需要了解扩展 built-ins 的工作原理。

不是通过定义一个简单的 class 扩展 HTMLButtonElement 得到一个按钮,你至少需要做三件额外的事情:

// define via the whole signature
customElements.define(
  "fab-button",
  FabButton,
  {extends: 'button'}
);

...还有...allow the polyfill to work

// 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;
}

最重要的,它在页面上最基本的表现形式是这样的

<button is="fab-button">+</button>

请记住,使用 ES6 classes super(...args) 将始终 return 当前上下文。它在那里授予超级构造函数没有 return 其他实例作为升级对象。

构造函数不是你的朋友

虽然听起来很刺耳,但自定义元素构造函数仅适用于 Shadow DOMaddEventListener,但实际上没有其他作用。

创建元素时不一定会升级。事实上,它很可能不会升级。

至少有 2 个错误提交给每个浏览器和 3 个关于自定义元素初始化的不一致行为,但最好的选择是一旦 connectedCallback 被调用,您确实拥有自定义元素节点内容。

connectedCallback() {
  this.slots = [...this.childNodes];
  this.render();
}

通过这种方式,您可以确保在 DOM 上实时渲染组件,而不是在 there is not even a content.

上渲染组件

我希望我回答你的问题的方式也警告你远离自定义元素 built-ins 如果这是一个新项目的开始:不幸的是,它们不是未来的安全赌注您的应用程序。

此致。