FireFox 中的自定义元素非法构造函数
Custom Elements Illegal Constructor in FireFox
我有一个带有以下构造函数的 CustomElement:
export default class SomeCustomElement extends HTMLElement {
constructor(templateId) {
super();
this.insertTemplateInstance(templateId);
}
...
}
我可以毫无问题地在 Chrome 中注册该元素。
但是使用 Firefox 和 webcomponents-loader.js
从 https://github.com/webcomponents/webcomponentsjs 加载的 polyfill 我在调用 super()
.
时收到错误消息 TypeError: Illegal constructor
有人知道是什么原因造成的吗?
更多背景:
自定义元素的注册过程如下:
window.addEventListener("WebComponentsReady", function () {
customElements.define(elementName, SomeCustomElement);
});
如果你不想出现这种错误,请使用 webcomponents-lite.js
而不是 webcomponent-loader.js
,这是因为如果你使用 [=15,polyfill 将被异步加载=].
下面的示例适用于 Firefox(以及所有现代浏览器):
class SomeCustomElement extends HTMLElement
{
constructor()
{
console.log( 'created' )
super()
}
connectedCallback() {
console.log( 'connected' )
this.innerHTML = "Hello"
}
}
customElements.define( 'c-e', SomeCustomElement )
<script src=https://rawgit.com/webcomponents/webcomponentsjs/master/webcomponents-lite.js></script>
<c-e></c-e>
但是,如果您仍想使用 webcomponents-loader.js
,则必须将自定义元素定义插入外部文件,并使用 HTML 导入加载它:
<link rel="import" href="my-element.html">
预先警告:我不是 html 进口的忠实粉丝。我偶然发现了这个试图让基于 ES 6 class 的自定义元素在 Firefox 中工作。对于基于已接受答案的条件 polyfill-loading-no-html-import 解决方案,请继续阅读...
有条件地加载 polyfill 有点棘手。根据@Supersharp 的 answer/comments,出于某种原因,polyfill 必须 同步加载(尽管官方文档中没有提及这一点)。所以现在你有两个没有吸引力的选择:无条件地包含它以获得必要的同步加载或......使用 document.write
:
<script>
;(function() {
var str = '';
// You could make this more fine-grained if desired by doing
// more feature detection and loading the minimal polyfill file
if (!window.customElements) str += '<script src="./node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>';
str += '<script src="./elements.js"></script>';
document.write(str);
})();
</script>
<foo-bar></foo-bar>
然后在 elements.js
:
class FooBar extends HTMLElement {
constructor () {
console.log("constructing");
super();
}
connectedCallback () {
console.log("connecting");
}
disconnectedCallback () {
console.log("disconnecting");
}
};
// Note that because of the synchronous loading we don't
// need to listen for the event
customElements.define('foo-bar', FooBar);
document.write
由于充分的理由而被广泛不喜欢,但恕我直言,这是一个合法的用例。请注意,这里的大多数反对意见(没有预取等)都可以通过使用服务工作者(对于支持它们的浏览器)来改善。
我有一个带有以下构造函数的 CustomElement:
export default class SomeCustomElement extends HTMLElement {
constructor(templateId) {
super();
this.insertTemplateInstance(templateId);
}
...
}
我可以毫无问题地在 Chrome 中注册该元素。
但是使用 Firefox 和 webcomponents-loader.js
从 https://github.com/webcomponents/webcomponentsjs 加载的 polyfill 我在调用 super()
.
TypeError: Illegal constructor
有人知道是什么原因造成的吗?
更多背景:
自定义元素的注册过程如下:
window.addEventListener("WebComponentsReady", function () {
customElements.define(elementName, SomeCustomElement);
});
如果你不想出现这种错误,请使用 webcomponents-lite.js
而不是 webcomponent-loader.js
,这是因为如果你使用 [=15,polyfill 将被异步加载=].
下面的示例适用于 Firefox(以及所有现代浏览器):
class SomeCustomElement extends HTMLElement
{
constructor()
{
console.log( 'created' )
super()
}
connectedCallback() {
console.log( 'connected' )
this.innerHTML = "Hello"
}
}
customElements.define( 'c-e', SomeCustomElement )
<script src=https://rawgit.com/webcomponents/webcomponentsjs/master/webcomponents-lite.js></script>
<c-e></c-e>
但是,如果您仍想使用 webcomponents-loader.js
,则必须将自定义元素定义插入外部文件,并使用 HTML 导入加载它:
<link rel="import" href="my-element.html">
预先警告:我不是 html 进口的忠实粉丝。我偶然发现了这个试图让基于 ES 6 class 的自定义元素在 Firefox 中工作。对于基于已接受答案的条件 polyfill-loading-no-html-import 解决方案,请继续阅读...
有条件地加载 polyfill 有点棘手。根据@Supersharp 的 answer/comments,出于某种原因,polyfill 必须 同步加载(尽管官方文档中没有提及这一点)。所以现在你有两个没有吸引力的选择:无条件地包含它以获得必要的同步加载或......使用 document.write
:
<script>
;(function() {
var str = '';
// You could make this more fine-grained if desired by doing
// more feature detection and loading the minimal polyfill file
if (!window.customElements) str += '<script src="./node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>';
str += '<script src="./elements.js"></script>';
document.write(str);
})();
</script>
<foo-bar></foo-bar>
然后在 elements.js
:
class FooBar extends HTMLElement {
constructor () {
console.log("constructing");
super();
}
connectedCallback () {
console.log("connecting");
}
disconnectedCallback () {
console.log("disconnecting");
}
};
// Note that because of the synchronous loading we don't
// need to listen for the event
customElements.define('foo-bar', FooBar);
document.write
由于充分的理由而被广泛不喜欢,但恕我直言,这是一个合法的用例。请注意,这里的大多数反对意见(没有预取等)都可以通过使用服务工作者(对于支持它们的浏览器)来改善。