FireFox 中的自定义元素非法构造函数

Custom Elements Illegal Constructor in FireFox

我有一个带有以下构造函数的 CustomElement:

export default class SomeCustomElement extends HTMLElement {
    constructor(templateId) {
        super();
        this.insertTemplateInstance(templateId);
    }
    ...
}

我可以毫无问题地在 Chrome 中注册该元素。

但是使用 Firefox 和 webcomponents-loader.jshttps://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 由于充分的理由而被广泛不喜欢,但恕我直言,这是一个合法的用例。请注意,这里的大多数反对意见(没有预取等)都可以通过使用服务工作者(对于支持它们的浏览器)来改善。