递归地将shadowRoot替换为innerHTML

时间:2019-07-05 11:21:42

标签: javascript html shadow-dom

我想获取带有shadowRoot元素的纯HTML。 网站上有很多shadowRoot元素,并且它们都是深层嵌套的。

我使用那段代码来实现它。但是它只提取一些元素

const getShadowDomHtml = (shadowRoot) => {
    let shadowHTML = '';
    for (let el of shadowRoot.childNodes) {
        shadowHTML += el.nodeValue || el.outerHTML;
    }
    return shadowHTML;
};


const replaceShadowDomsWithHtml = (rootElement) => {
    for (let el of rootElement.querySelectorAll('*')) {
        if (el.shadowRoot) {
            replaceShadowDomsWithHtml(el.shadowRoot);
            el.innerHTML += getShadowDomHtml(el.shadowRoot);
        }
    }
};

> replaceShadowDomsWithHtml(document.body);

> document.body.innerHTML

2 个答案:

答案 0 :(得分:0)

在创建Shadow DOM时,开发人员在将其附加到元素openclosed时指定一种模式。

open被提取,closed不被提取。

看看下面的代码片段,您将得到一个错误,因为没有参考就无法访问封闭的DOM的根。调用封闭的DOM的shadowRoot属性,它将返回null

const open = document.querySelector('#open'),
  closed = document.querySelector('#closed');
  
// Open
const openShadowRoot = open.attachShadow({ mode: "open" });
openShadowRoot.innerHTML = '<p>Open Shadow Root</p>'

// Closed
const closedShadowRoot = closed.attachShadow({ mode: "closed" });
closedShadowRoot.innerHTML = '<p>Closed Shadow Root</p>'

// Gets shadow roots
for (let el of document.querySelectorAll('div')) {
  console.log(el.shadowRoot.innerHTML);
}
<div id="open"></div>
<div id="closed"></div>

所以我想其中有些是关闭的,而另一些则没有。

答案 1 :(得分:0)

好的,我已经找到并自定义了适用于我的代码

const recursiveWalk = (node, func) => {
    const done = func(node);
    if (done) {
        return true;
    }

    if ('shadowRoot' in node && node.shadowRoot) {
        const done = recursiveWalk(node.shadowRoot, func);
        if (done) {
            return true;
        }
    }
    node = node.firstChild;

    while (node) {
        const done = recursiveWalk(node, func);
        if (done) {
            return true;
        }
        node = node.nextSibling;
    }
}

let html = '';

recursiveWalk(document.body, function (node) {
    html += node.nodeValue || node.outerHTML;
});

console.log(html);