首页 文章

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

提问于
浏览
2

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

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

我可以在Chrome中注册该元素而不会出现任何问题 .

但是使用Firefox和 webcomponents-loader.jshttps://github.com/webcomponents/webcomponentsjs加载的polyfill我在调用 super() 时得到ErrorMessage TypeError: Illegal constructor .

有人知道造成这种情况的原因吗?

更多背景:

注册自定义元素的方式如下:

window.addEventListener("WebComponentsReady", function () {
    customElements.define(elementName, SomeCustomElement);
});

2 回答

  • 0

    如果您不希望出现这种错误,请使用 webcomponents-lite.js 而不是 webcomponent-loader.js ,这是因为如果您使用 webcomponents-loader.js ,将会异步加载polyfills .

    以下示例适用于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 Imports加载它:

    <link rel="import" href="my-element.html">
    
  • 3

    提前警告:我不是html导入的忠实粉丝 . 我偶然发现了这个尝试让基于ES 6类的自定义元素在Firefox中运行 . 对于基于接受的答案的条件 - polyfill-loading-no-html-import解决方案,请继续阅读......

    有条件地加载polyfill有点棘手 . Per @ Supersharp的回答/评论,由于某种原因,必须同步加载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 ,但这是恕我直言,这是一个合法的用例 . 请注意,此处的大多数异议(无预取等)都可以通过使用服务工作者(对于支持它们的浏览器)来改善 .

相关问题