很难回答这个问题,因为很难理解从哪里开始。
TL;DR 解决方案虽然在这里,但需要大量解释。
扩展内置插件是 Web 规范中的鬼魂
不管WHATWG 怎么说,内置插件实际上是一种死亡规范,因为 Webkit 强烈反对它,而 Firefox 以及 Edge,甚至从未发布过自定义元素,也没有推动拥有它们。
因此,作为起点,不鼓励使用自定义元素 V1 规范扩展内置。
不过,您可能对 V0 很幸运,但这只是 Chrome API,它已经是那些为死而生的 API 之一(RIP WebSQL)。
我的 polyfill 按照定义遵循规范
document-register-element polyfill 与 V0 一起诞生,但在 V1 中进行了改进,尽可能地遵循规范,这就是为什么它可以扩展内置插件,因为 WHATWG 仍然包含该部分。
这也意味着您需要了解扩展内置插件的工作原理。
不是通过定义一个简单的类来扩展HTMLButtonElement
你得到一个按钮,你至少需要做三件额外的事情:
// define via the whole signature
customElements.define(
"fab-button",
FabButton,
{extends: 'button'}
);
...但也...允许 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;
}
最重要的是,它在页面上的最基本表示是这样的
<button is="fab-button">+</button>
请记住,使用 ES6 类super(...args)
将始终返回当前上下文。它在那里授予超级构造函数没有将其他实例作为升级对象返回。
构造函数不是你的朋友
听起来很刺耳,自定义元素的构造函数只与Shadow DOM
and一起工作addEventListener
,但实际上并没有。
创建元素时不一定要升级。事实上,它很可能不会升级。
每个浏览器至少有 2 个 bug 和 3 个关于自定义元素初始化的不一致行为,但最好的选择是一旦connectedCallback
被调用,你就真的拥有自定义元素节点内容。
connectedCallback() {
this.slots = [...this.childNodes];
this.render();
}
通过这种方式,您可以确定您确实在 DOM 上实时渲染了组件,而不是在没有 content 的情况下。
我希望我已经以某种方式回答了您的问题,同时警告您如果这是一个新项目的开始,请远离内置的自定义元素:不幸的是,对于您的应用程序的未来,它们不是一个安全的选择。
此致。