Update:
我已经概述了这 6 种方法中每种方法超过 1000 次运行的一些基本性能测试。getElementsByTagName
是最快的,但它做得半途而废,因为它不选择所有元素,而只选择一种特定类型的标签(我认为p
)并盲目地假设它的firstChild是一个文本元素。它可能有一点缺陷,但它是为了演示目的并将其性能与TreeWalker
. 在 jsfiddle 上自己运行测试查看结果。
- 使用树行者
- 自定义迭代遍历
- 自定义递归遍历
- Xpath查询
- 查询选择器全部
- 按标签名称获取元素
让我们假设有一个方法可以让你获得所有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);
}
}
}
按标签名称获取元素(障碍)
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