我们定义了这样的自定义元素......
<my-button>
Submit
</my-button>
和标准的customElements
定义
class MyButton extends HTMLElement{
constructor(){
super();
// our custom code...
this.innerHTML = ''; // ??? where did the 'Submit' go?
}
}
...
customElements.define('my-button',MyButton);
问题是,当试图获得innerHTML时,我们知道我们可以做像DOMContentLoaded
或window.onload
这样的事情。
但有时候我们想用代码动态创建'my-button'。被附加后“渲染”......
有没有标准的方法来做到这一点?它与connectedcallback()
和其他“连接”功能有关吗?
谢谢!
请注意 - 我尝试使用connectedCallback()
作为可能的解决方案,但这并没有解决问题。
在Web组件的构造函数中,您可以做什么,不能做什么,有一套规则。他们在下面。
但想到这个:
可以使用以下三种方法之一创建组件:
innerHTML
时,您可以将属性和子项添加到组件中,作为页面加载或innerHTML
的一部分。parent.innerHTML = '<super-hero name="Thor"><super-weapon value="Mjolnir"></super-weapon></my-comp>'.
document.createELement
来创建一个元素。在创建元素之前,您无法添加属性或子项。let superHero = document.createElement('super-hero');
let superWeapon = document.createElement('super-weapon');
superHero.setAttribute('name', 'Thor');
superWeapon.setAttribute('value', 'Mjolnir');
superHero.appendChild(superWeapon);
parent.appendChild(superHero)
new
实例化对象。就像document.createElement
一样,你必须等到元素创建之后再添加属性和子元素。let superHero = new SuperHero();
let superWeapon = new SuperWeapon();
superHero.setAttribute('name', 'Thor');
superWeapon.setAttribute('value', 'Mjolnir');
superHero.appendChild(superWeapon);
parent.appendChild(superHero)
创建组件后,它将添加到DOM中,这是在调用组件的connectedCallback
时。
所有这三种方式都归结为用new
实例化。 document.createElement
调用CustomElementRegistry.get
来获取该元素的构造函数,然后使用new
创建该对象。
并且innerHTML
解析HTML然后调用document.createElement
或使用new
来创建对象。
但是,这样做时,在调用元素的构造函数时,没有属性或子元素。事实上,当调用connectedCallback
时,可能没有任何子项或属性。这是observedAttributes
和attributeChangedCallback
被添加到规范中的一个原因。
规范中缺少的一件事是知道有人在将组件添加到DOM之前或之后添加或更改了子项。但是,如果你真的想知道孩子什么时候改变你可以使用MutationObserver
。
这就是构造函数中不存在子项或属性的原因。他们尚未加入。
在创作自定义元素构造函数时,作者受以下一致性要求的约束:
- 对super()的无参数调用必须是构造函数体中的第一个语句,以便在运行任何其他代码之前建立正确的原型链和此值。
- return语句不能出现在构造函数体内的任何位置,除非它是一个简单的早期返回(返回或返回此)。
- 构造函数不得使用document.write()或document.open()方法。
- 不得检查元素的属性和子元素,因为在非升级的情况下不会出现任何属性和子元素,并且依赖于升级会使元素变得不可用。
- 元素不得获得任何属性或子元素,因为这违反了使用createElement或createElementNS方法的消费者的期望。
- 通常,应尽可能将工作推迟到connectedCallback - 尤其是涉及获取资源或呈现的工作。但是,请注意,connectedCallback可以被多次调用,因此任何真正一次性的初始化工作都需要一个防护来防止它运行两次。
- 通常,构造函数应该用于设置初始状态和默认值,以及设置事件侦听器和可能的影子根。
在元素创建期间,直接或间接检查其中一些要求,如果不遵循它们,将导致无法通过解析器或DOM API实例化的自定义元素。