更新:
我已经为这 6 种方法中的每一种在 1000 次以上的运行中概述了一些基本性能测试。 getElementsByTagName 是最快的,但它完成了一半的工作,因为它不会选择所有元素,而只选择一种特定类型的标签(我认为p)并且盲目地假设它的 firstChild 是一个文本元素。它可能有点缺陷,但它用于演示目的并将其性能与TreeWalker 进行比较。 Run the tests yourselves on jsfiddle查看结果。
- 使用 TreeWalker
- 自定义迭代遍历
- 自定义递归遍历
- Xpath 查询
- querySelectorAll
- getElementsByTagName
让我们暂时假设有一种方法可以让您以本机方式获取所有Text 节点。您仍然需要遍历每个生成的文本节点并调用node.nodeValue 来获取实际文本,就像您对任何 DOM 节点所做的那样。所以性能问题不在于遍历文本节点,而是遍历所有非文本节点并检查它们的类型。我认为(基于结果)TreeWalker 的执行速度与getElementsByTagName 一样快,即使不是更快(即使 getElementsByTagName 玩有障碍)。
每个测试运行 1000 次。
方法 总毫秒 平均毫秒
--------------------------------------------------
文档.TreeWalker 301 0.301
迭代遍历器 769 0.769
递归遍历器 7352 7.352
XPath 查询 1849 1.849
查询选择器全部 1725 1.725
getElementsByTagName 212 0.212
每种方法的来源:
树行者
function nativeTreeWalker() {
var walker = document.createTreeWalker(
document.body,
NodeFilter.SHOW_TEXT,
null,
false
);
var node;
var textNodes = [];
while(node = walker.nextNode()) {
textNodes.push(node.nodeValue);
}
}
递归树遍历
function customRecursiveTreeWalker() {
var result = [];
(function findTextNodes(current) {
for(var i = 0; i < current.childNodes.length; i++) {
var child = current.childNodes[i];
if(child.nodeType == 3) {
result.push(child.nodeValue);
}
else {
findTextNodes(child);
}
}
})(document.body);
}
迭代树遍历
function customIterativeTreeWalker() {
var result = [];
var root = document.body;
var node = root.childNodes[0];
while(node != null) {
if(node.nodeType == 3) { /* Fixed a bug here. Thanks @theazureshadow */
result.push(node.nodeValue);
}
if(node.hasChildNodes()) {
node = node.firstChild;
}
else {
while(node.nextSibling == null && node != root) {
node = node.parentNode;
}
node = node.nextSibling;
}
}
}
querySelectorAll
function nativeSelector() {
var elements = document.querySelectorAll("body, body *"); /* Fixed a bug here. Thanks @theazureshadow */
var results = [];
var child;
for(var i = 0; i < elements.length; i++) {
child = elements[i].childNodes[0];
if(elements[i].hasChildNodes() && child.nodeType == 3) {
results.push(child.nodeValue);
}
}
}
getElementsByTagName(差点)
function getElementsByTagName() {
var elements = document.getElementsByTagName("p");
var results = [];
for(var i = 0; i < elements.length; i++) {
results.push(elements[i].childNodes[0].nodeValue);
}
}
XPath
function xpathSelector() {
var xpathResult = document.evaluate(
"//*/text()",
document,
null,
XPathResult.ORDERED_NODE_ITERATOR_TYPE,
null
);
var results = [], res;
while(res = xpathResult.iterateNext()) {
results.push(res.nodeValue); /* Fixed a bug here. Thanks @theazureshadow */
}
}
此外,您可能会发现此讨论很有帮助 - http://bytes.com/topic/javascript/answers/153239-how-do-i-get-elements-text-node