我正在尝试克隆阴影根,以便我可以将<content></content>
的实例与其相应的分布式节点交换。
我的方法:
var shadowHost = document.createElement('div');
var shadowRoot = shadowHost.createShadowRoot();
var clonedShadowRoot = shadowRoot.cloneNode(true);
不起作用,因为“ShadowRoot节点不可克隆”。
这样做的动机是我希望检索组合的阴影树,以便我可以使用渲染的HTML标记。
由于Shadow DOM的性质,这可能不起作用,克隆过程可能会破坏对分布式节点的引用。
编写影子树很可能是一个原生的功能,但是通过搜索w3c规范,我无法找到这样的方法。
有这样的原生方法吗?或者,如果不这样做,手动遍历(在过程中复制树)会起作用吗?
好。这有点疯狂,但这是我写的一个例程,它将克隆shadowRoot的子节点。这符合V1规范。
function cloneShadow(shadow) {
const frag = document.createDocumentFragment();
var nodes = [...shadow.childNodes];
nodes.forEach(
node => {
node.remove();
frag.appendChild(node.cloneNode(true));
shadow.appendChild(node);
}
);
return frag;
}
const s1 = document.querySelector('.shadow1');
const s2 = document.querySelector('.shadow2');
s1.attachShadow({mode:'open'}).innerHTML = `<h1>Header</h1>
<p>Content in a paragraph</p><slot></slot>`;
setTimeout(() => {
s2.attachShadow({mode:'open'}).appendChild(cloneShadow(s1.shadowRoot));}, 1000);
.shadow1 {
background-color: #F88;
}
.shadow2 {
background-color: #88F;
}
<div class="shadow1">
<p>SHADOW 1</p>
</div>
<div class="shadow2">
<p>SHADOW 2</p>
</div>
我不得不从shadowDOM中删除每个节点,然后克隆它,然后将其追加回shadowRoot。
我甚至添加了一个setTimeout
,这样你就可以看到它随时可用。
它甚至适用于插槽。
也许还有更多你想要完成的东西,但似乎解决无法使用cloneNode
的一种方法是创建一个镜像ShadowRoot
,然后从原始“克隆”innerHTML
。例如:
const shadowRoot = document.createElement('div').attachShadow({mode: 'open'});
shadowRoot.appendChild(document.createElement('p'));
console.log('Original shadow tree', shadowRoot.childNodes);
const cloneRoot = document.createElement('div').attachShadow({mode: 'open'});
cloneRoot.innerHTML = shadowRoot.innerHTML;
console.log('Cloned shadow tree', cloneRoot.childNodes);