我不知道如果我在正确的轨道上
目的:必须确保所有元素在shadowDOM结束
所以手动创建的HTML文件
<cardts-pile>
<cardts-card>A</cardts-card>
<cardts-card>B</cardts-card>
</cardts-pile>
在<cardts-pile>
的lightDOM创建卡
如果我然后将它们移到shadowDOM(ofcourse):
►<cardts-card>
从DOM(触发disconnectedCallback()
)除去
►<cardts-card>
再次加入(触发connectedCallback()
)
[见的console.log上运行代码片段如下]
我在card.connectedCallback()
更看中码
在“重新连接”它基本上是再次引发了完全相同的代码。
<cardts-card>
只是被移动,
所以connectedCallback
知道它并不需要再次运行代码。customElements.define('cardts-pile', class extends HTMLElement {
constructor(){
super();
this.attachShadow({mode: 'open'}).innerHTML='<slot></slot>';
}
connectedCallback() {
console.log('connect pile');
}
});
customElements.define('cardts-card', class extends HTMLElement {
constructor(){
super();
this.attachShadow({mode: 'open'}).innerHTML='<slot></slot>';
}
connectedCallback() {
console.log('connect card',this.innerText);
if (!this.getRootNode().host) // not in shadowDOM
this.parentNode.shadowRoot.insertBefore(this,null);//or appendChild
}
disconnectedCallback() {
console.log('disconnect card',this.innerText);
}
});
<cardts-pile>
<cardts-card>A</cardts-card>
<cardts-card>B</cardts-card>
</cardts-pile>
是否有可能移动节点没有DOM的变化?
否(据我了解阴影DOM)。
有没有开箱即用的代码检查,如果现有的只被感动?
我会用一个布尔标志:
connectedCallback() {
if ( !this.connected )
console.log( 'creation' )
else {
console.log( 'move' )
this.connected = true
}
(或者在disconnectedCallack
)
customElements.define('cardts-pile', class extends HTMLElement {
constructor(){
super();
this.attachShadow({mode: 'open'}).innerHTML='<slot></slot>';
this.shadowRoot.addEventListener( 'slotchange', ev => {
let node = this.querySelector( 'cardts-card' )
node && this.shadowRoot.append( node )
})
}
connectedCallback() {
console.log('connect pile');
}
});
customElements.define('cardts-card', class extends HTMLElement {
constructor(){
super();
this.attachShadow({mode: 'open'}).innerHTML='<slot></slot>';
}
connectedCallback() {
if ( !this.connected )
console.log( this.innerText + ' created' )
else
console.log( this.innerText + ' moved' )
this.connected = true
}
disconnectedCallback() {
if ( !this.moved )
console.log( 'moving ' + this.innerText );
else
console.log( 'really disconnected' )
this.moved = true
}
});
<cardts-pile>
<cardts-card>A</cardts-card>
<cardts-card>B</cardts-card>
</cardts-pile>
我应该做不同的东西?
你可以代替定义或升级<cardts-card>
后才未知元素被移动,如果可能的话,尽管我不认为这是一个很好的做法,除非你可以控制整个执行时间,例如与whenDefined()
或有序HTML和Javascript代码:
customElements.define('cardts-pile', Pile)
customElements.whenDefined('cardts-pile').then(() =>
customElements.define('cardts-card', Card)
)
在下面的例子中,你(这取决于它们之间的关系)之前或类Pile
后定义类Card
。
class Card extends HTMLElement {
constructor(){
super()
this.attachShadow({mode: 'open'}).innerHTML='<slot></slot>'
}
connectedCallback() {
console.log(this.innerText + ' connected')
}
disconnectedCallback() {
console.log(this.innerText + ' disconnected')
}
}
class Pile extends HTMLElement {
constructor() {
super()
this.attachShadow({mode: 'open'})
}
connectedCallback() {
console.log('connect pile')
this.shadowRoot.append(...this.querySelectorAll('cardts-card'))
}
}
window.onload = () => customElements.define('cardts-pile', Pile)
customElements.whenDefined('cardts-pile').then(() =>
customElements.define('cardts-card', Card)
)
<cardts-pile>
<cardts-card>A</cardts-card>
<cardts-card>B</cardts-card>
</cardts-pile>