<分区>
我有两个包装器:
function wrapSentences(str, tmpl) {
return str.replace(/[^\.!\?]+[\.!\?]+/g, tmpl || "<sentence>$&</sentence>")
}
和
function wrapWords(str, tmpl) {
return str.replace(/\w+/g, tmpl || "<word>$&</word>");
}
我在我们的扩展中使用这些来包装用户出于 TTS 和设置目的访问的任何网页上的每个单词和句子。
document.body 是每个网站上最原子化的元素,但是执行 body.innerHTML = wrapWords(body.innerText)
将(显然)替换不同文本节点之间的任何元素,从而破坏网站(的视觉部分)。我正在寻找一种方法来找到任何文本周围最接近的元素,而无需了解该元素的任何具体信息,因此我可以用包装等效项替换它,而无需以任何方式更改网站。
我发现了几个指向最深子节点的示例,但它们都依赖于传递一些扩展无法知道的内容(节点或 ID)。我们将使用 rangy 来突出显示,但有同样的问题......我总是最终不得不传递一个节点或 ID,而扩展程序在访问随机站点时无法意识到这一点。
需要传递节点的示例之一:
function replaceTextNodes(node, newText) {
if (node.nodeType === 3) {
//Filter out text nodes that contain only whitespace
if (!/^\s*$/.test(node.data)) {
node.data = newText;
}
} else if (node.hasChildNodes()) {
for (let i = 0, len = node.childNodes.length; i < len; ++i) {
replaceTextNodes(node.childNodes[i], newText);
}
}
}
如果需要,我很乐意更好地解释它。我担心我的措辞可能并不总是最好的,我知道这一点。