2010-05-26 4 views
1

Je veux récupérer tous les noeuds présents notamment DIV element.see la page de test ci-dessous (firefox)getElementsByTagName ne retourne pas les nœuds de commentaire javascript

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

Mais il ne me donne pas tag commentaires .. quel est le meilleur moyen de récupérer toutes les balises ??

+1

BTW personne ne en majuscules les noms d'éléments HTML plus. Dites juste. ;) – Tomalak

+0

@Tomalak: peut-être était-il un 'innerHTML' /' outerHTML' légèrement modifié et légèrement modifié? : - P –

Répondre

4

Le cœur du problème est que ces méthodes ...

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

... retour éléments, comme indiqué par leur nom. Cependant, les commentaires et les nœuds de texte ne sont pas des éléments. Ce sont des nœuds, mais pas des éléments.

Vous avez donc besoin de faire un peu de script DOM traditionnel à l'ancienne, en utilisant childNodes comme suggéré par Vincent Robert. Depuis - comme vous l'indiquez dans votre commentaire à lui - que .childNodes ne va une « couche » profonde, vous devez définir une fonction récursive pour trouver les nœuds de commentaire: (je nommer le mien 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

Avez-vous testé cela dans IE? La documentation MSDN pour [childNodes] (http: //msdn.microsoft.com/en-us/library/ms537445 \ (v = VS.85 \) .aspx) indique qu'il renvoie uniquement des éléments HTML et des objets TextNode via childNodes. La documentation pour [nodeType] (http: //msdn.microsoft.com/en-us/library/ms534191 \ (v = VS.85 \) .aspx) correspond à ceci, montrant les valeurs possibles comme '1 (Element) 'ou' 3 (TextNode) '. Matière à réflexion ... –

+0

@ La tête d'Andy E. - Non, je ne l'ai pas fait! Je tenais pour acquis que cela fonctionnerait dans IE car j'avais utilisé quelque chose de similaire pour trouver des nœuds de texte avant :(Bon appel. –

3

Vous pouvez utiliser .childNodes pour récupérer tous les enfants au lieu de .getElementsByTagName('*') qui ne renverra que des éléments enfants.

est ici une fonction pour récupérer tous les descendants d'un noeud 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; 
} 

Utilisation:

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

.childNodes ne fonctionne qu'à un seul niveau – Sourabh

+2

@Sourabh - Alors c'est l'heure des aventures avec récursivité! –

+0

ajouté une version récursive pour récupérer tous les descendants d'un noeud –

0

Vous devez utiliser la innerHtml puis utiliser un analyseur pour trouver les commentaires dans il.

+0

Ceci est une idée intéressante; Puisque les commentaires ne peuvent pas être définis à l'intérieur d'eux-mêmes, ils pourraient probablement être analysés/analysés beaucoup plus facilement que l'analyse complète de HTML. –

1

types de nœuds (non exhaustive):

  • Élément
  • texte
  • Commentaire

getElementsByTagName ne capte que les noeuds d'élément. childNodes, nextSibling, etc ramasser toutes sortes de nœuds. nextElementSibling ne reprend que les éléments.

0

Les commentaires sont des nœuds dans l'arborescence DOM, mais ils n'ont pas de nom de balise. La méthode getElementsByTagName renvoie uniquement les nœuds qui ont un nom de tag.

Si vous voulez tous les nœuds, vous devez traverser l'arborescence DOM, en utilisant la collection childNodes de chaque élément.

3

Si vous ne se soucient pas de IE, vous pouvez éviter l'approche récursive et éventuellement améliorer les performances (non testé) à l'aide d'un TreeWalker en utilisant 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)); 
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; 
} 
Questions connexes