:
我已经概述了这6种方法在1000次运行中的每种的一些基本性能测试。getElementsByTagName
是最快的,但它完成了一半的工作,因为它不会选择所有元素,而是仅选择一种特定类型的标签(我认为p
),并且盲目地假设其firstChild是文本元素。它可能没有什么瑕疵,但它只是出于演示目的,并将其性能与TreeWalker
。
让我们暂时假设有一种方法可以让您Text
本地获取所有节点。您仍然必须遍历每个结果文本节点并调用node.nodeValue
以获取实际文本,就像处理任何DOM节点一样。因此,性能问题不在于遍历文本节点,而在于遍历非文本的所有节点并检查其类型。我认为(基于结果)它的TreeWalker
执行速度与一样快getElementsByTagName
,甚至还不及它(甚至在getElementsByTagName播放残障的情况下)。
Ran each test 1000 times.
Method Total ms Average ms
--------------------------------------------------
document.TreeWalker 301 0.301
Iterative Traverser 769 0.769
Recursive Traverser 7352 7.352
XPath query 1849 1.849
querySelectorAll 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;
}
}
}
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);
}
}
}
(handicap)
function getElementsByTagName() {
var elements = document.getElementsByTagName("p");
var results = [];
for(var i = 0; i < elements.length; i++) {
results.push(elements[i].childNodes[0].nodeValue);
}
}
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 */
}
}