gpt4 book ai didi

javascript - 在没有 disconnectedCallback 的情况下将元素从 light DOM 移动到 ShadowDOM

转载 作者:行者123 更新时间:2023-11-29 23:07:00 28 4
gpt4 key购买 nike

我想知道我是否在正确的轨道上

目标:需要确保所有元素最终都在 shadowDOM 中

因此手动创建的 HTML 文件

<cardts-pile>
<cardts-card>A</cardts-card>
<cardts-card>B</cardts-card>
</cardts-pile>

<cardts-pile>lightDOM 中创建卡片

如果我然后将它们移动到 shadowDOM(当然):

<cardts-card>从 DOM 中删除(触发 disconnectedCallback() )
<cardts-card>再次添加(触发 connectedCallback() )

[请参阅下面关于 Run Code Snipper 的 console.log]

我在 card.connectedCallback() 中有更多花哨的代码
在“重新连接”时,它基本上会再次触发完全相同的代码。

问题

  1. 是否可以在不更改 DOM 的情况下移动节点?

  2. 是否有 OOTB 代码来检查现有 <cardts-card>只是被感动了,
    所以connectedCallback知道它不需要再次运行代码。

  3. 我应该做些不同的事情吗,
    让那些 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>

最佳答案

Is it possible to move nodes without DOM changes?

没有(据我所知 Shadow DOM)。

Is there OOTB code to check if an existing is only being moved?

我会使用 bool 标志:

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>

Should I be doing something different?

您可以改为定义或升级 <cardts-card>只有在 unknown 元素被移动之后,如果可能的话,我认为这不是一个好的做法,除非你可以控制整个执行时间,例如 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>

关于javascript - 在没有 disconnectedCallback 的情况下将元素从 light DOM 移动到 ShadowDOM,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54562388/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com