我们有这样定义的自定义元素...
<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
的事情。
,但有时我们想使用代码动态地动态创建“我的按钮” 。并在添加后使其“呈现” ...
是否有标准方法可以做到这一点?它与connectedcallback()
和其他“已连接”功能有关吗?
谢谢!
请注意-我已尝试使用connectedCallback()
作为可能的解决方案,但这不能解决问题。
答案 0 :(得分:0)
关于Web组件的构造函数中可以做什么和不能做什么的一组规则。他们在下面。
但是请考虑一下:
可以通过以下三种方式之一创建组件:
innerHTML
时,您可以在页面加载或innerHTML
的一部分中向组件添加属性和子代。 / li>
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实例化自定义元素。