无法通过其默认构造函数动态实例化我的自定义元素
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>
这很好用。正如我所期望的那样,我收到了这两个警报。
我创建了一个我想在我的网站上使用的自定义元素,当我在 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>
这很好用。正如我所期望的那样,我收到了这两个警报。