了解处理订单的customElements



在父自定义元素拥有其自定义方法之前,父自定义元素可以访问其子元素。

class CustomParent extends HTMLElement {
connectedCallback() {
// works
this.children[0].textContent = "bar";
// works
setTimeout(() => this.children[0].test(), 0);
// throws a Type error
this.children[0].test();
}
}
customElements.define("custom-parent", CustomParent);

class CustomChild extends HTMLElement {
test() {
this.textContent = "baz";
}
}
customElements.define("custom-child", CustomChild);
document.body.innerHTML = `
<custom-parent>
<custom-child>foo</custom-child>  
</custom-parent>
`;

这怎么可能,推迟this.children[0].test()安全吗?

这是由于自定义元素的升级过程。

第一步:执行document.body.innerHTML = '<custom-parent><custom-child>foo</custom-child></custom-parent>'时,两个元素将作为未知元素插入页面

第二步:父元素是首先升级。它可以访问其子级(然后更新其textContent属性(作为未知元素。但它无法访问自定义元素test()方法。。。因为它还不是自定义元素!

第三步:子元素在之后立即升级,现在获得test()方法。

第四步:延迟的test()调用在逻辑上起作用:-(

请参阅下面的示例。它使用querySelectorAll( ':not(:defined)' )来显示子级是在其父级之后升级的。

class CustomParent extends HTMLElement {
constructor() { super() ; console.log( 'parent upgraded') }
connectedCallback() {
console.log( 'parent connected', this.children[0].outerHTML )
// works
this.children[0].textContent = 'bar'    
// works
setTimeout( () => this.children[0].test() )
// throws a Type error
try { 
this.children[0].test() 
} catch ( e ) { 
//this shows the parent is upgraded, but not its child 
var not_upgraded = document.querySelectorAll( ':not(:defined)' )
console.log( 'not upgraded: ', ...not_upgraded )    
}    
}
}
customElements.define( 'custom-parent', CustomParent )
class CustomChild extends HTMLElement {
constructor() { super() ; console.log( 'child upgraded') }      
test() { this.textContent = 'baz' }
}
customElements.define( 'custom-child', CustomChild ) 
document.body.innerHTML = `
<custom-parent>
<custom-child>foo</custom-child>  
</custom-parent>`

最新更新