无法通过其默认构造函数动态实例化我的自定义元素

Unable to instantiate my custom element dynamically through its default constructor

我创建了一个我想在我的网站上使用的自定义元素,当我在 html 文档中声明它时,构造函数被调用并且元素被实例化并显示而没有任何错误。但是当我想在代码中实例化它时,它似乎缺少使用 new CustomElement() 对其构造函数的引用。

<html>
<head>

<!-- 
    ...
-->

<script src="/custom_elements.js" defer ></script>   

<!-- 
    ...
-->


<style>



</style>



<script >


    function init(){

        var ele = new CustomElement();
        // !! does not work



    }



</script>

</head>


<body onLoad="init();" >

<custom-element></custom-element>
<!-- works -->

</body>
</html>

// 在 custom_elements.js 中 class 定义为

class CustomElement extends HTMLElement {

    constructor() {
        super();

        // code that gets displayed flawlessly when instantiated from html 


    }



}


customElements.define('custom-element', CustomElement );

错误说:"CustomElement not defined"..

所以似乎缺少一些参考,因为当我将 CustomElement 的定义粘贴到我的代码所在的标记中时,它就可以工作了。 那么我如何加载我的脚本引用它的文件,而不仅仅是 HTML 代码.. 感谢您就这些功能如何运作提供任何建议

EDIT/REASON 错误

所以看起来这个实现在逻辑上没有错,但是我的 custom_elements.js 文件有一个 if/else 子句,其中定义了元素.. 这是

if(!customElementsSupported){

    // custom elements not supported action

}else{

    // definitions of custom elements

}

我假设这一定是将自定义元素放在本地范围内,从而阻止我的函数访问它们

defer - 脚本将在页面解析完成后执行。

意思是 - 你的 CustomElement 将在调用后执行。

如何避免 - 删除 defer 并在 body 标签末尾之前使用脚本标签。

正如我在评论中所述,您可以在 <script> 标签中删除 defer

或者您只需要知道 class 何时可用 customElements.whenDefined(name);

如果您在 init 函数中进行此更改,它将起作用:

function init(){
  let ele;
  customElements.whenDefined('custom-element').then(
    function() {
      ele = new CustomElement();
    }
  );
}

这会等待元素被定义,直到 class 存在时才会发生。这样您就可以安全地以任何您想要的方式实例化您的元素。

更新

您也可以使用 document.createElement 创建您的对象,但您仍然需要等到元素被定义。

function init(){
  customElements.whenDefined('custom-element').then(
    function() {
      let ele = document.createElement('custom-element');
      // Do things with your element
    }
  );
}

进一步更新

我创建了两个文件:

custom_elements.js

class CustomElement extends HTMLElement {
  constructor() {
    super();
    alert('constructor');
  }

  connectedCallback() {
    alert('connectedCallback');
  }
}

customElements.define('custom-element', CustomElement);

test.html

<!DOCTYPE html>
<html lang="en">
<head>
  <script src="custom_elements.js" defer></script>
  <script>
  function init() {
    customElements.whenDefined('custom-element').then(
      function () {
        let ele = new CustomElement();
        document.body.appendChild(ele);
      }
    );
  }
  </script>
</head>
<body onLoad="init();">
</body>
</html>

这很好用。正如我所期望的那样,我收到了这两个警报。