有什么方法可以获取textNode文档中所有对象的集合?
textNode
getElementsByTagName()对于Elements来说效果很好,但是textNodes不是Elements。
getElementsByTagName()
更新: 我意识到这可以通过遍历DOM来完成-如以下建议所示。我知道如何编写一个DOM- walker函数来查看文档中的每个节点。我希望有某种浏览器本机的方法可以做到这一点。毕竟,我可以<input>通过一个内置调用获得所有s,但不是全部textNodes 有点奇怪。
<input>
更新 :
我已经概述了这6种方法在1000次运行中的每种的一些基本性能测试。getElementsByTagName是最快的,但它完成了一半的工作,因为它不会选择所有元素,而是仅选择一种特定类型的标签(我认为p),并且盲目地假设其firstChild是文本元素。它可能没有什么瑕疵,但它只是出于演示目的,并将其性能与TreeWalker。
getElementsByTagName
p
TreeWalker
让我们暂时假设有一种方法可以让您Text本地获取所有节点。您仍然必须遍历每个结果文本节点并调用node.nodeValue以获取实际文本,就像处理任何DOM节点一样。因此,性能问题不在于遍历文本节点,而在于遍历非文本的所有节点并检查其类型。我认为(基于结果)它的TreeWalker执行速度与一样快getElementsByTagName,甚至还不及它(甚至在getElementsByTagName播放残障的情况下)。
Text
node.nodeValue
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; } } }
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 (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); } }
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 */ } }