我想知道我是否在正确的轨道上
目标:需要确保所有元素最终都在shadowDOM中
因此手动创建了HTML文件
<cardts-pile>
<cardts-card>A</cardts-card>
<cardts-card>B</cardts-card>
</cardts-pile>
以 light DOM <cardts-pile>
如果我随后将它们移至shadowDOM(当然):
►<cardts-card>
已从DOM中删除(触发disconnectedCallback()
)
►再次添加<cardts-card>
(触发connectedCallback()
)
[请参见下面的Run Code Snipper上的console.log]
我在card.connectedCallback()
中有更多精美的代码
在“重新连接”上,基本上是触发完全相同的相同代码再次。
是否可以在不更改DOM的情况下移动节点?
是否存在OOTB代码以检查是否仅移动了现有 <cardts-card>
,
因此connectedCallback
知道不需要再次运行代码。
我应该做些不同的事情吗,
使得这些lightDOM元素立即以shadowDOM结尾?
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>
答案 0 :(得分:1)
是否可以在不更改DOM的情况下移动节点?
否(据我对Shadow DOM的了解)。
是否存在OOTB代码来检查是否仅在移动现有文件?
我将使用一个布尔标志:
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>
我应该做些不同的事情吗?
您只能在移动 unknown 元素之后定义或升级<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>