Как я могу клонировать ShadowRoot?
Я пытаюсь клонировать теневой корень, чтобы я мог поменять экземпляры <content></content>
на соответствующие распределенные узлы.
Мой подход:
var shadowHost = document.createElement('div');
var shadowRoot = shadowHost.createShadowRoot();
var clonedShadowRoot = shadowRoot.cloneNode(true);
не работает, так как "узлы ShadowRoot не являются клонируемыми."
Мотивация для этого состоит в том, что я хочу получить составленное дерево теней, чтобы я мог использовать визуализированную разметку HTML.
Это может не работать из-за природы Shadow DOM, ссылка на распределенные узлы, вероятно, будет нарушена процессом клонирования.
Составление теневого дерева, вероятно, является встроенной функцией, но, просмотрев спецификацию w3c, я не смог найти такой метод.
Есть ли такой нативный метод? Или, если это не удастся, сработает ли ручной обход (копирование дерева в процессе)?
Ответы
Ответ 1
ХОРОШО. Это немного сумасшествие, но я написал подпрограмму, которая клонирует детей 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>
Ответ 2
Возможно, есть что-то большее, чего вы пытаетесь достичь, но кажется, что одним из способов обойти невозможность использования 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);