与textNodes等效的getElementsByTagName()

有什么方法可以获取textNode文档中所有对象的集合?

getElementsByTagName()对于Elements来说效果很好,但是textNodes不是Elements。

我意识到这可以通过遍历DOM来完成-如以下建议所示。我知道如何编写一个DOM-

walker函数来查看文档中的每个节点。我希望有某种浏览器本机的方法可以做到这一点。毕竟,我可以<input>通过一个内置调用获得所有s,但不是全部textNodes

有点奇怪。

回答:

我已经概述了这6种方法在1000次运行中的每种的一些基本性能测试。getElementsByTagName是最快的,但它完成了一半的工作,因为它不会选择所有元素,而是仅选择一种特定类型的标签(我认为p),并且盲目地假设其firstChild是文本元素。它可能没有什么瑕疵,但它只是出于演示目的,并将其性能与TreeWalker

  1. Using a TreeWalker
  2. Custom Iterative Traversal
  3. Custom Recursive Traversal
  4. Xpath query
  5. querySelectorAll
  6. getElementsByTagName

让我们暂时假设有一种方法可以让您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 */

}

}

以上是 与textNodes等效的getElementsByTagName() 的全部内容, 来源链接: utcz.com/qa/406360.html

回到顶部