我试图替换标签之间的所有文本,我想知道最快的方式。
一个例子是尝试用任意字符串helloWorld替换所有文本,以便:
<div>
<div>
RandomText1
<div>
RandomText2
</div>
</div>
</div>
成为这个:
<div>
<div>
helloWorld
<div>
helloWorld
</div>
</div>
</div>
我目前的方法是:
这对我来说会非常慢,尤其是尝试为大型文档执行此操作并且必须多次重复此过程。有更快的方法吗?
答案 0 :(得分:3)
您不需要解析每个元素来查找文本节点,您只需递归遍历元素的childNodes
属性
var newText = 'hello world';
function replaceTextNodes(node) {
node.childNodes.forEach(function(el) {
if (el.nodeType === 3) { // If this is a text node, replace the text
if (el.nodeValue.trim() !== "") { // Ignore this node it it an empty text node
el.nodeValue = newText;
}
} else { // Else recurse on this node
replaceTextNodes(el);
}
});
}
var onClick = replaceTextNodes.bind(null, document.querySelector('#container'));
document.querySelector('#replace').addEventListener('click', onClick);
&#13;
<div id='container'>
<div>
RandomText1
<div>
RandomText2
<ul>
<li>RandomText3</li>
</ul>
</div>
</div>
</div>
<button id="replace">Replace</button>
&#13;
答案 1 :(得分:2)
nodeIterator
非常快。嵌套节点没有任何问题,无论它们埋藏多深。注意:添加了6级的红色文本。详情请参阅代码段。
<强>段强>
/* Create a custom filter which will...
||...the 3rd parameter of createNodeIterator method...
*/
function textFilter(node) {
// if .nodeType is 3 (3 is text, 1 is element)
if (node.nodeType === 3) {
// Set .nodeValue to 'hellowWorld'
node.nodeValue = 'helloWorld';
// Return NodeFilter object to accept node
return NodeFilter.FILTER_ACCEPT;
}
// Otherwise ignore node
return NodeFilter.FILTER_SKIP;
}
function findText() {
// Reference the rootNode
var content = document.querySelector('body');
/* Create nodeIterator passing
|| content or rootNode
|| NodeFilter object or WhatToShow property
|| Custom filter function
*/
var iterator = document.createNodeIterator(content, NodeFilter.SHOW_TEXT, textFilter);
// Advance to the next sibling or descend to node's children nodes
var node = iterator.nextNode();
// While there is a node...
while (node) {
// ...Go on to it...rinse, lather, and repeat
node = iterator.nextNode();
}
}
findText();
.mark {
color: red;
}
<div>
<div>
RandomText1
<div>
RandomText2
</div>
</div>
</div>
<div>
<div>
<div>
<div>
<div>
<div class='mark'>
6 Deep!
</div>
</div>
</div>
</div>
</div>
<div>
RandomText1
<div>
RandomText2
</div>
</div>
</div>
<div>
<div>
RandomText1
<div>
RandomText2
</div>
</div>
</div>
<div>
<div>
RandomText1
<div>
RandomText2
</div>
</div>
</div>
<div>
<div>
RandomText1
<div>
RandomText2
</div>
</div>
</div>
答案 2 :(得分:2)
使用TreeWalker对象作为DOM遍历的最快工具。
可以使用Document.createTreeWalker()方法创建 TreeWalker 。
function replaceAllText(newText) {
var walker = document.createTreeWalker(
document.body, // root node
NodeFilter.SHOW_TEXT, // filtering only text nodes
null,
false
);
while (walker.nextNode()) {
if (walker.currentNode.nodeValue.trim()) // if it's not empty(whitespaced) node
walker.currentNode.nodeValue = newText;
}
}
replaceAllText("helloWorld");
<div>
<div>
RandomText1
<div>
RandomText2
</div>
</div>
</div>
https://developer.mozilla.org/en-US/docs/Web/API/Document/createTreeWalker
答案 3 :(得分:0)
浏览器完成的DOM搜索速度非常快,并且也进行了优化。 所以,我建议在DOM元素上添加一些需要更改的公共类,然后使用该类标识符对它们进行操作。
此外,
仅供参考,document.getElementById()
适用于DFS并且非常有效。
答案 4 :(得分:0)
遍历HTML而不是像这样找到nodeValue:
document.querySelectorAll('div').forEach(function(o,i){
console.log(o.firstChild && o.firstChild.nodeValue);
})