getElementsByTagName() 等效于 textNodes [英] getElementsByTagName() equivalent for textNodes
问题描述
有没有办法获取文档中所有 textNode
对象的集合?
getElementsByTagName()
适用于 Elements,但 textNode
s 不是 Elements.
更新:我意识到这可以通过遍历 DOM 来实现 - 正如以下许多建议的那样.我知道如何编写一个 DOM-walker 函数来查看文档中的每个节点.我希望有一些浏览器原生的方式来做到这一点.毕竟,我可以通过单个内置调用获取所有 ,但不是所有
textNode
,这有点奇怪.
更新:
我已经对这 6 种方法中的每一种进行了 1000 次运行的一些基本性能测试.getElementsByTagName
是最快的,但它做了一半的工作,因为它没有选择所有元素,而是只选择一种特定类型的标签(我认为 p
)并盲目假设它的 firstChild 是一个文本元素.它可能没有什么缺陷,但用于演示目的并将其性能与 TreeWalker
进行比较.自己在 jsfiddle 上运行测试以查看结果.
- 使用 TreeWalker
- 自定义迭代遍历
- 自定义递归遍历
- Xpath 查询
- querySelectorAll
- getElementsByTagName
让我们暂时假设有一种方法可以让您本地获取所有 Text
节点.您仍然需要遍历每个结果文本节点并调用 node.nodeValue
来获取实际文本,就像处理任何 DOM 节点一样.所以性能问题不在于遍历文本节点,而是遍历所有非文本节点并检查它们的类型.我认为(根据结果)TreeWalker
的执行速度与 getElementsByTagName
一样快,如果不是更快的话(即使 getElementsByTagName 播放有障碍).
每种方法的来源:
树行者
function nativeTreeWalker() {var walker = document.createTreeWalker(文档正文,NodeFilter.SHOW_TEXT,空值,错误的);无功节点;var textNodes = [];while(node = walker.nextNode()) {textNodes.push(node.nodeValue);}}
递归树遍历
function customRecursiveTreeWalker() {var 结果 = [];(函数 findTextNodes(当前){for(var i = 0; i < current.childNodes.length; i++) {var child = current.childNodes[i];如果(子节点类型 == 3){result.push(child.nodeValue);}别的 {findTextNodes(child);}}})(document.body);}
迭代树遍历
function customIterativeTreeWalker() {var 结果 = [];var root = document.body;var node = root.childNodes[0];而(节点!= null){if(node.nodeType == 3) {/* 在这里修复了一个错误.谢谢@theazureshadow */结果.推(节点.节点值);}如果(节点.hasChildNodes()){节点 = node.firstChild;}别的 {while(node.nextSibling == null && node != root) {节点 = node.parentNode;}节点 = node.nextSibling;}}}
querySelectorAll
function nativeSelector() {var elements = document.querySelectorAll("body, body *");/* 在这里修复了一个错误.谢谢@theazureshadow */var 结果 = [];var 孩子;for(var i = 0; i
getElementsByTagName(障碍)
function getElementsByTagName() {var elements = document.getElementsByTagName("p");var 结果 = [];for(var i = 0; i
XPath
function xpathSelector() {var xpathResult = document.evaluate(//*/文本()",文档,空值,XPathResult.ORDERED_NODE_ITERATOR_TYPE,空值);var 结果 = [], res;while(res = xpathResult.iterateNext()) {结果.推(res.nodeValue);/* 在这里修复了一个错误.谢谢@theazureshadow */}}
此外,您可能会发现此讨论很有帮助 - http://bytes.com/topic/javascript/answers/153239-how-do-i-get-elements-text-node
Is there any way to get the collection of all textNode
objects within a document?
getElementsByTagName()
works great for Elements, but textNode
s are not Elements.
Update: I realize this can be accomplished by walking the DOM - as many below suggest. I know how to write a DOM-walker function that looks at every node in the document. I was hoping there was some browser-native way to do it. After all it's a little strange that I can get all the <input>
s with a single built-in call, but not all textNode
s.
Update:
I have outlined some basic performance tests for each of these 6 methods over 1000 runs. getElementsByTagName
is the fastest but it does a half-assed job, as it does not select all elements, but only one particular type of tag ( i think p
) and blindly assumes that its firstChild is a text element. It might be little flawed but its there for demonstration purpose and comparing its performance to TreeWalker
. Run the tests yourselves on jsfiddle to see the results.
- Using a TreeWalker
- Custom Iterative Traversal
- Custom Recursive Traversal
- Xpath query
- querySelectorAll
- getElementsByTagName
Let's assume for a moment that there is a method that allows you to get all Text
nodes natively. You would still have to traverse each resulting text node and call node.nodeValue
to get the actual text as you would do with any DOM Node. So the issue of performance is not with iterating through text nodes, but iterating through all nodes that are not text and checking their type. I would argue (based on the results) that TreeWalker
performs just as fast as getElementsByTagName
, if not faster (even with getElementsByTagName playing handicapped).
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
Source for each method:
TreeWalker
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);
}
}
Recursive Tree Traversal
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);
}
Iterative Tree Traversal
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 */
}
}
Also, you might find this discussion helpful - http://bytes.com/topic/javascript/answers/153239-how-do-i-get-elements-text-node
这篇关于getElementsByTagName() 等效于 textNodes的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!