getElementsByTagName不会在javascript中返回注释节点

时间:2010-05-26 12:03:28

标签: javascript

我想检索特定DIV元素中存在的所有节点。请参阅下面的测试页面 (火狐)

 <HTML>
 <HEAD>
  <TITLE> New Document </TITLE>
  <META NAME="Generator" CONTENT="EditPlus">
  <META NAME="Author" CONTENT="">
  <META NAME="Keywords" CONTENT="">
  <META NAME="Description" CONTENT="">
 <script>
 function processTags()
 {
    var chNodes = document.getElementById('foo').childNodes ;
console.log(chNodes);   
console.log("------");  

  var chNodes = document.getElementById('foo').getElementsByTagName('*') ;
 console.log(chNodes); 
}
</script>
 </HEAD>

 <BODY onload="processTags();">
  <div id="foo">
  <!-- this is a comment -->this is some text ? <span>this is inside span</span>
  <div><p>test</p>test<div>
  </div>
 </BODY>
</HTML>

但它没有给我评论标签..检索所有标签的最佳方法是什么?

7 个答案:

答案 0 :(得分:4)

问题的核心是这些方法......

document.getElementById(...)
document.getElementsByTagName(...)

...返回元素,如其名称所示。但是,注释和文本节点不是元素。它们是节点,但不是元素。

所以你需要像Vincent Robert建议的那样使用childNodes做一些传统的老式DOM脚本。因为 - 正如你在评论中指出的那样 - .childNodes只有一层'深层',你需要定义一个递归函数来查找注释节点:(我命名为document.getCommentNodes()})

document.getCommentNodes = function() {
    function traverseDom(curr_element) { // this is the recursive function
        var comments = new Array();
        // base case: node is a comment node
        if (curr_element.nodeName == "#comment" || curr_element.nodeType == 8) {
            // You need this OR because some browsers won't support either nodType or nodeName... I think...
            comments[comments.length] = curr_element;
        }
        // recursive case: node is not a comment node
        else if(curr_element.childNodes.length>0) {
            for (var i = 0; i<curr_element.childNodes.length; i++) {
                // adventures with recursion!
                comments = comments.concat(traverseDom(curr_element.childNodes[i]));
            }
        }
        return comments;
    }
   return traverseDom(document.getElementsByTagName("html")[0]);
}

答案 1 :(得分:3)

您可以使用.childNodes来检索所有子项,而不是仅返回子元素的.getElementsByTagName('*')

这是一个检索DOM节点的所有后代的函数:

function getDescendantNodes(node)
{
    var ret = [];
    if( node )
    {
        var childNodes = node.childNodes; 
        for( var i = 0, l = childNodes.length; i < l; ++i )
        {
            var childNode = childNodes[i];
            ret.push(childNode);
            ret = ret.concat(getDescendantNodes(childNode));
        }
    }
    return ret;
}

用法:

getDescendantNodes(document.getElementById("foo"));

答案 2 :(得分:3)

如果您不关心IE,可以使用TreeWalker使用document.createTreeWalker来避免递归方法并可能提高性能(未经测试):

function getCommentNodes(containerNode) {
    var treeWalker = document.createTreeWalker(containerNode,
        NodeFilter.SHOW_COMMENT, null, false);
    var comments = [];
    while (treeWalker.nextNode()) {
        comments.push(treeWalker.currentNode);
    }
    return comments;
} 

console.log(getCommentNodes(document.body));

答案 3 :(得分:1)

节点类型(非详尽):

  • 元素
  • 文本
  • 注释

getElementsByTagName仅选择Element节点。 childNodesnextSibling等等,可以获取各种节点。 nextElementSibling只会选择元素。

答案 4 :(得分:0)

您需要使用innerHtml,然后使用解析器在其中查找注释。

答案 5 :(得分:0)

注释是DOM树中的节点,但它们没有标记名称。 getElementsByTagName方法仅返回具有标记名称的节点。

如果您想要所有节点,则必须使用每个元素的childNodes集合遍历DOM树。

答案 6 :(得分:0)

var getComments = function(oNode) {
    var oChild,
        aComments = [];
    oNode = oNode || document;
    for (var n=0; n<oNode.childNodes.length; n++) {
        oChild = oNode.childNodes[n];
        switch (oChild.nodeType) {
            case 1: // Element
                aComments = aComments.concat(getComments(oChild));
                break;
            case 8: // Comment
                aComments.push(oChild);
                break;
        }
    }
    return aComments;
}