tags:

views:

121

answers:

6

Hi ,

I want to retrieve all the nodes present in particular DIV element.see the below test page (firefox)

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

But it does not give me comments tag.. what is the best way to retrieve all tags ??

+3  A: 

You can use .childNodes to retrieve all children instead of .getElementsByTagName('*') which will only return child elements.

Here is a function to retrieve all descendants of a DOM node:

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

Usage:

getDescendantNodes(document.getElementById("foo"));
Vincent Robert
.childNodes works only at single level
Sourabh
@Sourabh - Then it's time for adventures with recursion!
LeguRi
added a recursive version to retrieve all descendants of a node
Vincent Robert
A: 

You would need to use the innerHtml and then use a parser to find the comments in it.

Snake
This is an interesting idea; since comments can't be defined inside themselves, they could probably be exracted/parsed much more easily than fully parsing HTML.
LeguRi
+1  A: 

Node types (non exhaustive):

  • Element
  • Text
  • Comment

getElementsByTagName only picks up Element nodes. childNodes, nextSibling, etc. pick up all kinds of nodes. nextElementSibling only picks up Elements.

Delan Azabani
A: 

Comments are nodes in the DOM tree, but they don't have a tag name. The getElementsByTagName method only returns nodes that have a tag name.

If you want all nodes, you have to traverse the DOM tree, using the childNodes collection of each element.

Guffa
+2  A: 

The heart of the problem is that these methods...

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

... return elements, as indicated by their names. However, comments and text nodes are not elements. They are nodes, but not elements.

So you need to do some traditional old fashioned DOM scripting, using childNodes like Vincent Robert suggested. Since - as you indicate in your comment to him - that .childNodes only goes one 'layer' deep, you need to define a recursive function to find the comment nodes: (I'm naming mine 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]);
}
LeguRi
@Richard: Have you tested this in IE? The MSDN documentation for [childNodes](http://msdn.microsoft.com/en-us/library/ms537445\(v=VS.85\).aspx) states that it only returns HTML elements and TextNode objects via childNodes. The documentation for [nodeType](http://msdn.microsoft.com/en-us/library/ms534191\(v=VS.85\).aspx) corresponds with this, showing the possible values as `1 (Element)` or `3 (TextNode)`. Food for thought...
Andy E
@Andy E's head - No, I didn't! I took for granted it would work in IE as I'd used something similar to find text nodes before :( Good call.
LeguRi
A: 

If you don't care about IE, you could avoid the recursive approach and possibly improve performance (untested) by using a TreeWalker using 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));
Tim Down