对于复活节彩蛋,我希望能够用常量字符串替换网页上的每个单词。现有问题的重点是替换某些单词,不包含许多其他元素的元素,或使用诸如JQuery之类的库。应保留结构,即<li>Some text <span>link</span> more text</li>
应成为<li>Lorem Lorem <span>Lorem</span> Lorem Lorem</li>
。
如果我像这样走DOM:
recur (el) {
if (typeof el === 'undefined') {
el = document.body
}
for (let e of el.childNodes) {
if (e.nodeType === 1) {
recur(e)
} else if (e.nodeType === 3) {
console.log(e)
}
}
}
我获得了许多#text
元素和看起来像字符串的东西。我怎么能真正改变它们?我尝试分配父数组中的相应元素,但这不起作用:
Uncaught TypeError: Failed to set an indexed property on 'NodeList': Index property setter is not supported.
修改此类文本节点的父节点上的innerHTML属性是否更好?
或者你会推荐一种不同的方法吗?仅限CSS的解决方案也很棒。
答案 0 :(得分:4)
多么有趣!您可以获取并分配给文本节点的nodeValue
。正则表达式将至少与/[\w\x7f-\xff]+/g
非常接近(十六进制值与特殊字符的很大一部分匹配)。
See here)
(function recur (el) {
if (typeof el === 'undefined') {
el = document.body
}
for (let e of el.childNodes) {
if (e.nodeType === Node.ELEMENT_NODE) {
recur(e)
} else if (e.nodeType === Node.TEXT_NODE) {
e.nodeValue = e.nodeValue.replace(/[\w\x7f-\xff]+/g, 'lorem')
}
}
})();
<html>
<head>
<title>
A Simple HTML Document
</title>
</head>
<body>
<p>This is a very schön HTML document</p>
<p>It only has <b>two</b> paragraphs</p>
</body>
</html>
答案 1 :(得分:2)
我强烈建议您考虑使用TreeWalker,一个用于此目的的DOM API - 遍历DOM树。它可以找到文档中的所有文本节点,并且非常有效地找到它们,因为现代浏览器在本机代码中运行这样的API调用。
第一个参数是您要开始搜索的节点,第二个参数是要查找的节点类型。在这种情况下,我们从document.body
开始寻找所有textNode
。然后,在while
循环中,您在节点上执行所需的任何操作,然后转到下一个。
通过这种植入,你不必处理尴尬的内部标签或空白区域 - 所有文本都很好地捆绑在一起。并且,它将比您在客户端JS中为树遍历编写的任何内容都快。
const matchAllExceptWhitespace = /\w+/g;
const treeWalker = document.createTreeWalker(document.body, NodeFilter.SHOW_TEXT, null, false);
const word = 'Lorem';
let node;
while (node = treeWalker.nextNode()) {
node.textContent = node.textContent.replace(matchAllExceptWhitespace, word);
}
<h1>A paragraph</h1>
<p>This is a sentence.</p>
<ul>
<li>Some text <span>link</span> more text</li>.
</ul>
答案 2 :(得分:1)
这是最简单的方法之一(从this answer借来一些帮助):
IsWin64
&#13;
function ReplaceChildText(node, replaceText) {
//Is this a text node?
if (node.nodeType === 3) {
//Simply replace the value with your regex:
node.nodeValue = node.nodeValue.replace(/\w+/g, replaceText);
} else {
//Loop through all the children, to look for more text nodes
for (let child of node.childNodes) {
//Yay, recursion
ReplaceChildText(child, replaceText);
}
}
}
ReplaceChildText(document.body, 'Loreum');
&#13;