Naviguer entre les nœuds

Parent Previous Next



Naviguer entre les nœuds



Nous avons vu précédemment qu'on utilisait les méthodes getElementById() et getElementsByTagName()pour accéder aux éléments HTML. Une fois que l'on a atteint un élément, il est possible de se déplacer de façon un peu plus précise, avec toute une série de méthodes et de propriétés que nous allons étudier ici.


La propriété parentNode


La propriété parentNode permet d'accéder à l'élément parent d'un élément. Regardez ce code :

<blockquote>

  <p id="myP">Ceci est un paragraphe !</p>

</blockquote>


Admettons qu'on doive accéder à myP, et que pour une autre raison on doive accéder à l'élément <blockquote>, qui est le parent de myP. Il suffit d'accéder à myP puis à son parent, avec parentNode :

var paragraph = document.getElementById('myP');

var blockquote = paragraph.parentNode;


nodeType et nodeName


nodeType et nodeName servent respectivement à vérifier le type d'un nœud et le nom d'un nœud.nodeType retourne un nombre, qui correspond à un type de nœud. Voici un tableau qui liste les types possibles, ainsi que leurs numéros (les types courants sont mis en gras) :

Numéro

Type de nœud

1

Nœud élément

2

Nœud attribut

3

Nœud texte

4

Nœud pour passage CDATA (relatif au XML)

5

Nœud pour référence d'entité

6

Nœud pour entité

7

Nœud pour instruction de traitement

8

Nœud pour commentaire

9

Nœud document

10

Nœud type de document

11

Nœud de fragment de document

12

Nœud pour notation


nodeName, quant à lui, retourne simplement le nom de l'élément, en majuscule. Il est toutefois conseillé d'utiliser toLowerCase() (ou toUpperCase()) pour forcer un format de casse et ainsi éviter les mauvaises surprises.

var paragraph = document.getElementById('myP');

alert(paragraph.nodeType + '\n\n' + paragraph.nodeName.toLowerCase());



Lister et parcourir des nœuds enfants
firstChild et lastChild

Comme leur nom le laisse présager, firstChild et lastChild servent respectivement à accéder au premier et au dernier enfant d'un nœud.

<!doctype html>

<html>

  <head>

    <meta charset="utf-8" />

    <title>Le titre de la page</title>

  </head>

 

  <body>

    <div>

      <p id="myP">Un peu de texte, <a>un lien</a> et <strong>une portion en emphase</strong></p>

    </div>

 

    <script>

      var paragraph = document.getElementById('myP');

      var first = paragraph.firstChild;

      var last  = paragraph.lastChild;

 

      alert(first.nodeName.toLowerCase());

      alert(last.nodeName.toLowerCase());

    </script>

  </body>

</html>



En schématisant l'élément myP précédent, on obtient ceci :



Schéma de l'élément myP



Le premier enfant de <p> est un nœud textuel, alors que le dernier enfant est un élément <strong>.

Dans le cas où vous ne souhaiteriez récupérer que les enfants qui sont considérés comme des éléments HTML (et donc éviter les nœuds #text par exemple), sachez qu'il existe les propriétésfirstElementChild et lastElementChild. Ainsi, dans l'exemple précédent, la propriétéfirstElementChild renverrait l'élément <a>.
Malheureusement, il s'agit là de deux propriétés récentes, leur utilisation est donc limitée aux versions récentes des navigateurs (à partir de la version 9 concernant Internet Explorer).


nodeValue et data


Changeons de problème : il faut récupérer le texte du premier enfant, et le texte contenu dans l'élément<strong>, mais comment faire ?

Il faut soit utiliser la propriété nodeValue soit la propriété data. Si on recode le script précédent, nous obtenons ceci :

var paragraph = document.getElementById('myP');

var first = paragraph.firstChild;

var last  = paragraph.lastChild;

 

alert(first.nodeValue);

alert(last.firstChild.data);



first contient le premier nœud, un nœud textuel. Il suffit de lui appliquer la propriété nodeValue (oudata) pour récupérer son contenu ; pas de difficulté ici. En revanche, il y a une petite différence avec notre élément <strong> : vu que les propriétés nodeValue et data ne s'appliquent que sur des nœuds textuels, il nous faut d'abord accéder au nœud textuel que contient notre élément, c'est-à-dire son nœud enfant. Pour cela, on utilise firstChild (et non pas firstElementChild), et ensuite on récupère le contenu avecnodeValue ou data.


childNodes


La propriété childNodes retourne un tableau contenant la liste des enfants d'un élément. L'exemple suivant illustre le fonctionnement de cette propriété, de manière à récupérer le contenu des éléments enfants :

<body>

  <div>

    <p id="myP">Un peu de texte <a>et un lien</a></p>

  </div>

 

  <script>

    var paragraph = document.getElementById('myP');

    var children  = paragraph.childNodes;

 

    for (var i = 0, c = children.length; i < c; i++) {

           

      if (children[i].nodeType === 1) { // C'est un élément HTML

        alert(children[i].firstChild.data);

      } else { // C'est certainement un nœud textuel

        alert(children[i].data);

      }

         

    }

  </script>

</body>



nextSibling et previousSibling

nextSibling et previousSibling sont deux propriétés qui permettent d'accéder respectivement au nœud suivant et au nœud précédent.

<body>

  <div>

    <p id="myP">Un peu de texte, <a>un lien</a> et <strong>une portion en emphase</strong></p>

  </div>

 

  <script>

    var paragraph = document.getElementById('myP');

    var first = paragraph.firstChild;

    var next  = first.nextSibling;

 

    alert(next.firstChild.data); // Affiche « un lien »

  </script>

</body>



Dans cet exemple, on récupère le premier enfant de myP, et sur ce premier enfant on utilise nextSibling, qui permet de récupérer l’élément <a>. Avec ça, il est même possible de parcourir les enfants d'un élément, en utilisant une boucle while :

<body>

  <div>

    <p id="myP">Un peu de texte <a>et un lien</a></p>

  </div>

 

  <script>

    var paragraph = document.getElementById('myP');

    var child = paragraph.lastChild; // On prend le dernier enfant

 

    while (child) {

         

      if (child.nodeType === 1) { // C'est un élément HTML

        alert(child.firstChild.data);

      } else { // C'est certainement un nœud textuel

        alert(child.data);

      }

         

      child = child.previousSibling; // À chaque tour de boucle, on prend l'enfant précédent

     

    }

  </script>

</body>



Pour changer un peu, la boucle tourne « à l'envers », car on commence par récupérer le dernier enfant et on chemine à reculons.

Tout comme pour firstChild et lastChild, sachez qu'il existe les propriétésnextElementSibling et previousElementSibling qui permettent, elles aussi, de ne récupérer que les éléments HTML. Ces deux propriétés ont les mêmes problèmes de compatibilité quefirstElementChild et lastElementChild.


Attention aux nœuds vides


En considérant le code HTML suivant, on peut penser que l'élément <div> ne contient que trois enfants<p> :

<div>

  <p>Paragraphe 1</p>

  <p>Paragraphe 2</p>

  <p>Paragraphe 3</p>

</div>


Mais attention, car ce code est radicalement différent de celui-ci :

<div><p>Paragraphe 1</p><p>Paragraphe 2</p><p>Paragraphe 3</p></div>


En fait, les espaces entre les éléments tout comme les retours à la ligne sont considérés comme des nœuds textuels (enfin, cela dépend des navigateurs) ! Ainsi donc, si l'on schématise le premier code, on obtient ceci :



Schéma de notre premier code



Alors que le deuxième code peut être schématisé comme ça :



Schéma de notre deuxième code



Heureusement, il existe une solution à ce problème ! Les attributs firstElementChildlastElementChild,nextElementSibling et previousElementSibling ne retournent que des éléments HTML et permettent donc d'ignorer les nœuds textuels. Ils s'utilisent exactement de la même manière que les attributs de base (firstChildlastChild, etc.). Cependant, ces attributs ne sont pas supportés par Internet Explorer 8 et ses versions antérieures et il n'existe pas d'autre possibilité.


Créé avec HelpNDoc Personal Edition: Générateur de documentation complet

Site à deux balles