LE MODELE OBJET DU DOCUMENT

Introduction

Le JavaScript s'appuie de plus en plus sur le DOM. Il permet, entre autres, de visualiser, d'ajouter ou d'enlever des éléments du document HTML.

Lorsque du code HTML est interprété par un navigateur, celui-ci crée, à partir de ce code, une interface de programmation appelée "modèle objet du document", ou "document objet model" en anglais, ou plus simplement DOM. Les navigateurs évoluant avec le temps, il existe plusieurs niveaux pour le DOM, le dernier étant le niveau 3 datant de 2004.

Une page HTML est constituée de balises à l'intérieur desquelles se trouvent d'autres balises. Du fait de cette forme hiérarchique, le DOM construit une arborescence de la structure du document et de ses éléments.

Dans l'exemple ci-dessus, on trouve :

Chaque élément, noeud ou texte, à l’exception du noeud de premier niveau, la racine <html>, est contenu dans un autre élément, son parent. Cet élément peut, en retour, contenir d’autres éléments enfants. On notera que les textes n’ont jamais d’enfants.

Visualiser les éléments du DOM

Accéder à un élément

Solution classique

On accède aux éléments du DOM avec les propriétés de l'interface "document" :

Propriété Utilité
document.documentElement Permet d'accéder au premier élément du DOM, le noeud html.
document.body Permet d'accéder à la partie body du document.
document.getElementsByTagName(balise) Retourne un tableau donnant accès aux divers noeuds trouvés.
document.getElementById(identifiant) Permet d'accéder à un élément auquel on a associé un identifiant unique.
document.getElementsByClassName(classe) Retourne un tableau donnant accès aux divers éléments de même classe.

Exemple :

<!DOCTYPE html>
<html>
  <head>
  <meta charset="utf-8">
  <style>
    .vert { color: #0a0; }
  </style>
  <script>
    onload=function() {
      alert(document.documentElement.innerHTML);
      alert(document.body.innerHTML);
      alert(document.getElementsByTagName("P")[1].innerHTML);
      alert(document.getElementById("para").innerHTML);
      alert(document.getElementsByClassName("vert")[1].innerHTML);
    };
  </script>
  </head>
  <body>
    <h1>Un titre...</h1>
    <p id="para" class="vert">Un texte...</p>
    <p><input type="button" value="OK"></p>
    <div id="vue" class="vert">La suite du texte...</div>
  </body>
</html>

Sinon, chaque élément du DOM possède aussi des propriétés :

Propriété Utilité
parentNode Permet d'accéder à l'élément parent, si parent il y a.
childNodes Retourne un tableau donnant accès aux divers éléments enfants.
firstChild Permet d'accéder au premier élément enfant.
lastChild Permet d'accéder au dernier élément enfant.

Dans l'exemple d'application ci-dessous, lorsqu'on clique sur le bouton "OK", le nombre d'éléments enfants du noeud "body" s'affiche dans une petite fenêtre.

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <script>
      function voir() {
        var ch="";
        ch+="Nombre d'enfants du noeud body : ";
        ch+=document.body.childNodes.length;
        alert(ch);
      }
    </script>
  </head>
  <body>
    <h1>Un titre...</h1>
    <p id="para">Un texte...</p>
    <p><input type="button" value="OK" onclick="voir();"></p>
    <div id="vue">La suite du texte...</div>
  </body>
</html>

Solution plus récente

Deux méthodes, "querySelector()" et "querySelectorAll()", simplifient la sélection d'éléments dans l'arbre du DOM. Elles prennent pour paramètre un sélecteur CSS sous la forme d'une chaîne de caractères.

Propriété Utilité
querySelector() Retourne le premier élément trouvé.
querySelectorAll() Retourne un tableau contenant tous les éléments trouvés.

Dans l'exemple ci-dessous, "couleur" est un tableau donnant accès à tous le éléments de classes "vert" ou "bleu".

var couleur=document.querySelectorAll('.vert , .bleu');

Une convention

Parce que "document.getElementById" est un nom plutôt long pour une opération assez commune, l’abréger par la variable $ est devenu une convention assez commune au sein des développeurs JavaScript. Attention à ne pas confondre cette variable avec l'objet $ de jQuery!

function $(id) { return document.getElementById(id); }

Identifier un élément

La propriété "nodeType" permet de savoir si un élément représente un noeud ou un texte. Elle contient un nombre, 1 pour un noeud et 3 pour un texte.

Les noeuds ont une propriété "nodeName", indiquant le type de balise HTML qu’ils représentent.

Exemple de code :

for (var i=0; i<document.body.childNodes.length; i++) {
  ch+="Type de l'enfant "+i+" : "+document.body.childNodes[i].nodeType+"<br>";
  ch+="Nom de l'enfant "+i+" : "+document.body.childNodes[i].nodeName+"<br><br>";
}

Visualiser le contenu d'un élément

Il y a deux cas de figures, selon que l'élément soit un noeud ou un texte :

Exemple de code :

alert(document.body.innerHTML);
alert(document.body.childNodes[1].firstChild.nodeValue);
ch+=document.body.innerHTML+"<br><br>";
ch+=document.body.childNodes[1].firstChild.nodeValue;

Inspecteur du DOM

L’utilisation d'un inspecteur DOM aide à comprendre le contenu d'une page HTML.

Exemple de code :

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Test DOM</title>
  </head>
  <body>
    <h1>Un titre...</h1>
    <p id="para">Un paragraphe...</p>
  </body>
</html>

Résultat donné par l’inspecteur DOM de Firefox :

Modifier les éléments du DOM

Ajouter un élément

Modifier les propriétés "innerHTML" d’un noeud ou "nodeValue" d’un texte changera son contenu. Mais l'ancien contenu est remplacé par le nouveau. L'objectif ici est d'ajouter du contenu à celui déjà existant ou de supprimer une partie seulement du contenu déjà présent.

L’objet document possède les méthodes "createElement" et "createTextNode". La première est utilisée pour créer un noeud, la seconde pour créer un texte.

balisage=document.createElement("H2");
sous_titre=document.createTextNode("Un sous-titre...");

Pour mettre le sous-titre dans l’élément "h2", puis ajouter cet élément au document, une solution consiste à faire appel à la méthode "appendChild". Elle peut être appelée sur chaque noeud.

balisage.appendChild(sous_titre);
document.body.appendChild(balisage);

Plus simplement peut-être, on peut aussi écrire :

balisage=document.createElement("H2");
balisage.innerHTML="Un sous-titre...";
document.body.appendChild(balisage);

Enlever un élément

La méthode "removeChild" supprime un élément enfant, noeud ou texte. Elle doit être appelée sur le parent du noeud à supprimer, en lui donnant l’enfant comme argument.

Exemple de code :

document.body.removeChild(document.body.childNodes[1]);

Autre exemple, permettant de supprimer une ligne de tableau en cliquant sur le lien correspondant.

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <script>
      function suppr(n) {
        ligne_a_sup=document.getElementById(n);
        ligne_a_sup.parentNode.removeChild(ligne_a_sup);
      }
    </script>
  </head>
  <body>
    <table border="1">
      <tr id="l0"><td>Ligne 1</td><td onclick="suppr('l0');">Sup</td></tr>
      <tr id="l1"><td>Ligne 2</td><td onclick="suppr('l1');">Sup</td></tr>
      <tr id="l2"><td>Ligne 3</td><td onclick="suppr('l2');">Sup</td></tr>
      <tr id="l3"><td>Ligne 4</td><td onclick="suppr('l3');">Sup</td></tr>
      <tr id="l4"><td>Ligne 5</td><td onclick="suppr('l4');">Sup</td></tr>
    </table>
  </body>
</html>

Un code similaire, qui permet de se passer des identifiants :

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <script>
      function suppr(ligne_a_sup) {
        ligne_a_sup.parentNode.removeChild(ligne_a_sup);
      }
    </script>
  </head>
  <body>
    <table border="1">
      <tr><td>Ligne 1</td><td onclick="suppr(this.parentNode);">Sup</td></tr>
      <tr><td>Ligne 2</td><td onclick="suppr(this.parentNode);">Sup</td></tr>
      <tr><td>Ligne 3</td><td onclick="suppr(this.parentNode);">Sup</td></tr>
      <tr><td>Ligne 4</td><td onclick="suppr(this.parentNode);">Sup</td></tr>
      <tr><td>Ligne 5</td><td onclick="suppr(this.parentNode);">Sup</td></tr>
    </table>
  </body>
</html>

Changer le contenu d'un élément

Pour remplacer le contenu d'un élément par un autre contenu, il faut modifier la propriété "innerHTML" de l'élément.

Par exemple :

document.getElementById("identifiant").innerHTML=ch;

Modifier le style d'un élément

Pour changer la valeur d'une propriété de style, il suffit de modifier la propriété "style" de l'élément.

Exemples :

document.getElementById("identifiant").style.display="none";
document.getElementById("identifiant").style.color="#2b6";

Pour changer la valeur de l'attribut "class" d'un l'élément, il faut modifier la propriété "className".

Exemple :

document.getElementById("identifiant").className="nouvelle_classe";

Ajouter un attribut à un élément

On vient de voir comment créer une balise avec du contenu. On peut également ajouter un attribut de balise, avec la méthode "setAttribute".

cadre=document.createElement("iframe");
cadre.setAttribute('src','http://eleydet.free.fr/');
document.body.appendChild(cadre);