getElementsByTagName()等效于textNodes [英] getElementsByTagName() equivalent for textNodes

查看:174
本文介绍了getElementsByTagName()等效于textNodes的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有没有办法获取文档中所有 textNode 对象的集合?

Is there any way to get the collection of all textNode objects within a document?

getElementsByTagName()适用于Elements,但 textNode 不是元素。

getElementsByTagName() works great for Elements, but textNodes are not Elements.

更新:我意识到这可以通过走DOM来完成 - 下面的建议。我知道如何编写一个查看文档中每个节点的DOM-Walker函数。我希望有一些浏览器本地的方式来做到这一点。毕竟有一点奇怪的是,我可以通过一个内置的调用获得所有的< input> ,但不能全部 textNode s。

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 textNodes.

推荐答案

更新

我在1000次运行中概述了这6种方法中的每一种的基本性能测试。 getElementsByTagName 是最快的,但它做了半分工作,因为它不选择所有元素,而只有一种特定类型的标签(我认为 p ),并盲目地假定它的firstChild是一个文本元素。它可能没有什么缺陷,但它的演示目的,并将其性能与 TreeWalker 进行比较。 在jsfiddle上运行测试查看结果。

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.


  1. 使用TreeWalker

  2. 自定义迭代遍历

  3. 自定义递归遍历

  4. Xpath查询

  5. querySelectorAll

  6. getElementsByTagName

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

让我们假设有一种方法可以让你自然地得到所有文本节点。您仍然必须遍历每个生成的文本节点,并调用 node.nodeValue 以获得与任何DOM节点相同的实际文本。因此,性能问题不是通过文本节点迭代,而是遍历不是文本的所有节点并检查其类型。我会争辩(基于结果), TreeWalker 的执行速度与 getElementsByTagName 一样快,如果不是更快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);
    }
}

递归树遍历 / p>

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);
}

迭代树遍历

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

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 (障碍)

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 */
    }
}

另外,你可能会发现这讨论有帮助 - http:// bytes。 com / topic / javascript / answers / 153239-how-do-i-get-elements-text-node

Also, you might find this discussion helpful - http://bytes.com/topic/javascript/answers/153239-how-do-i-get-elements-text-node

这篇关于getElementsByTagName()等效于textNodes的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆