對于這個問題,我還沒有看到令人滿意的答案。這基本上是這個問題的重復,但它被不當關閉并且給出的答案是不夠的。
我想出了我自己的解決方案,我將在下面發布。
這對于網頁抓取很有用,或者在我的情況下,在處理自定義元素的 javascript 庫上運行測驗。我確保它產生了我想要的輸出,然后我使用這個函式來抓取給定測驗輸出的 HTML,并使用復制的 HTML 作為預期輸出來比較將來的測驗。
uj5u.com熱心網友回復:
這是一個可以執行請求的函式。請注意,它會忽略 html 注釋和其他邊緣內容。但它使用 shadowRoots 檢索常規元素、文本節點和自定義元素。它還處理開槽模板內容。它沒有經過詳盡的測驗,但似乎可以很好地滿足我的需求。
像extractHTML(document.body)或一樣使用它extractHTML(document.getElementByID('app'))。
function extractHTML(node) {
// return a blank string if not a valid node
if (!node) return ''
// if it is a text node just return the trimmed textContent
if (node.nodeType===3) return node.textContent.trim()
//beyond here, only deal with element nodes
if (node.nodeType!==1) return ''
let html = ''
// clone the node for its outer html sans inner html
let outer = node.cloneNode()
// if the node has a shadowroot, jump into it
node = node.shadowRoot || node
if (node.children.length) {
// we checked for children but now iterate over childNodes
// which includes #text nodes (and even other things)
for (let n of node.childNodes) {
// if the node is a slot
if (n.assignedNodes) {
// an assigned slot
if (n.assignedNodes()[0]){
// Can there be more than 1 assigned node??
html = extractHTML(n.assignedNodes()[0])
// an unassigned slot
} else { html = n.innerHTML }
// node is not a slot, recurse
} else { html = extractHTML(n) }
}
// node has no children
} else { html = node.innerHTML }
// insert all the (children's) innerHTML
// into the (cloned) parent element
// and return the whole package
outer.innerHTML = html
return outer.outerHTML
}
uj5u.com熱心網友回復:
只有使用mode:"open"設定創建了shadowRoots 才能從外部訪問 shadowRoots。
然后,您可以下潛到元素和shadowRoots用的東西,如:
const shadowDive = (
el,
selector,
match = (m, r) => console.warn('match', m, r)
) => {
let root = el.shadowRoot || el;
root.querySelector(selector) && match(root.querySelector(selector), root);
[...root.children].map(el => shadowDive(el, selector, match));
}
注意:如果 Web 組件樣式基于 shadowDOM 行為,則提取原始 HTML 毫無意義;你會失去所有正確的造型。
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/354847.html
標籤:javascript 网页抓取 影子领域 自定义元素 原生网络组件
上一篇:(C語言篇)三子棋的實作
