Javascript - Pour rendre vos pages interactives

Auteur: Mohamed CHINY Durée necessaire pour le cours de Javascript - Pour rendre vos pages interactives Niveau recommandé pour le cours de Javascript - Pour rendre vos pages interactives Supports vidéo non disponibles pour ce cours Exercices de renforcement disponibles pour ce cours Quiz disponible pour ce cours

Page 19: Objet Document et DOM en Javascript (Partie 1)

Toutes les pages

Généralités

L'objet Document est hiérarchiquement placé sous l'objet window. Il permet de manipuler tous les objets qui sont inclus dans le documents HTML (images, textes, formulaires...). Il s'agit sans doute de l'objet le plus riche et le plus important, car dorénavant, nous aurons à notre dispositions des outils qui permettent de changer de fond en comble le contenu et le design d'une page d'une manière dynamique.

Quand on parle de l'objet document il y a un autre terme qui surgit automatiquement, c'est le DOM.

Document Objet Model: DOM

DOM qui signifie Document objet Model est un outil qui permet d'accéder au document. Il s'agit plus précisément d'une interface qui standardise la manière d'accès aux document structurés en balises comme HTML ou XML. D'ailleurs, chaque élément du document fait partie du model DOM.

Le DOM n'est pas propre au Javascript mais il est pris en charge par de nombreux autres langages de programmation tels que PHP et Perl et bien d'autres. Cependant, c'est en Javascript qu'il a gagné en popularité, ce qui est totalement justifié vu les exploits qu'il permet de réaliser au niveau d'un document balisé, notamment, une page Web.

Arborescence et nœuds

Nous avons déjà parlé de la hiérarchie des objets en Javascript. Il s'agit en fait de la manière dont sont présentés les différents éléments constituant le contenu (un objet parent qui contient de objets enfants qui, à leurs tours, contiennent d'autres objets et ainsi de suite).

L'ensemble des ces objets constituent une arborescences (connue aussi par le nom arbre HTML, si le document en question est HTML). Cet arbre est en fait une structures d'éléments qui représentent des nœuds.

Il existe deux types de nœuds, nœuds éléments et nœuds texte. Les nœuds éléments sont tout simplement les balises et t les nœuds textes sont les textes contenus dans un document HTML.

Exemple:
<div>Bonjour <span>à tous</spans></div>
Ce bout de code HTML représente deux nœuds élément <div> et <span>. <div> est, dans ce cas, le parent et <span> l'enfant. Nous avons aussi deux nœuds textes "Bonjour" qui est l'enfant de l'élément <div> et "à tous" qui est l'enfant de l'élément <span>.
Notez que les nœuds élément peuvent avoir autant d'enfant que l'on souhaite. Par contre, les nœuds texte n'en contiennent jamais.

Méthodes et sous-objets

Méthodes de base de l'objet document

Il existe de nombreux méthodes (et attributs) qui s'appliquent sur l'objet document. Cependant nous allons voir les plus connus.
  • write(): La méthode write() permet d'écrire la chaîne de caractères passée en paramètre directement dans le document.
  • writeln(): La méthode writeln() permet d'écrire dans le document en ajoutant un retour à la ligne.

Exemple:
document.write("Bonjour") ; // Affiche "Bonjour" dans la page.
document.writeln("Bonjour") ; // Affiche "Bonjour" suivi d'un retour à la ligne dans la page.
Le retour à ligne généré par la méthode writeln() est appliqué sur le code et pas sur le résultat affiché sur le navigateur. Pour prendre en compte le retour à la ligne dans la page Web, il faut penser à déclarer le script dans la balise <pre>. D'ailleurs, ces deux méthodes sont rarement utilisés.

Sous objets de document

Trois sous-objets sont fréquemment utilisés:
  • images: Cet objet retourne un tableau qui contient tous les objets de type image (c'est à dire les balises <img>). La première image du document est indexée par 0, la deuxième par 1 et ainsi de suite. L'attribut le plus utilisé de cet objet est src qui permet de changer la source de l'image dynamiquement.
  • forms: Cet objet retourne un tableau qui contient tous les formulaires du document (les balises <form>).
  • body: Cet objet fait référence à la balise <body>. Les attributs les plus courants pour cet objets sont:
    • scrollHeight: (pour document.body.scrollHeight) permet de connaitre la hauteur du corps du document. C'est à dire, la hauteur de la zone du navigateur qui accueille le contenu.
    • scrollTop: (pour document.body.scrollTop) permet de connaitre de combien de pixels la page a défilé du haut (si la barre de défilement est affichée suite à un débordement du contenu).


Exemple 1:
<img src="image1.jpg" />
<img src="image2.jpg" />
<img src="image3.jpg" />
<script language="javascript">
   for(i=0;i<document.images.length;i++)
      document.images[i].src="image4.jpg";
</script>
Dans cet exemple, on change dynamiquement la source des 3 balises <img> par "image4.jpg". Nous avons appliqué l'attribut length à l'objet images pour connaitre le nombre d'images dans le document.

Exemple 2:
<form>
   <input type="text" name="login" />
</form>
<script language="javascript">
   document.forms[0].login.value="ABC";
</script>
Dans cet exemple, on accède à la zone de texte nommée "login" hiérarchiquement. Nous avons appelé le formulaire qui la contient par l'objet forms qui fait référence à tous les formulaires du document. L'index 0 désigne le premier formulaire déclaré.

Exemple 3:
<input type="button" value="Afficher le scrollTop" onClick="alert(document.body.scrollTop+' pixels')" />
Ce code permet de connaitre la hauteur de la partie du document qui reste en haut.

Autres façons pour accéder aux sous objets de document

Jusqu'ici nous avons vu comment écrire directement dans le document et comment accéder aux images et formulaires déclarés. Cependant, il existe d'autres méthodes qui permettent d'accéder plus facilement aux différents objets de tout type d'un document. Il s'agit d'ailleurs des méthodes les plus utilisés par les développeurs:
  • getElementById(): Cette méthode permet d'accéder à un objet quelconque en l'identifiant par la valeur de son attribut id. Nous avons déjà eu l'occasion de vois cet attribut en CSS. Sa valeur est unique dans tout le document. C'est cette valeur qui sera déclarée dans les parenthèses de la méthode en tant que chaîne de caractères.
  • getElementsByTagName(): Cette méthode permet d'accéder tous les objets correspondant à la balise (tag) déclarée entre les parenthèses en tant que chaîne de caractères. Elle retourne un tableau qui renferme tous les nœuds du type désigné.

Exemple:
<img src="image1.jpg" id="im1" />
<img src="image2.jpg" />
<img src="image3.jpg" />
<script language="javascript">
   document.getElementById("im1").src="image4.jpg";
   for(i=1;i<document.getElementsByTagName("img").length;i++)
      document.getElementsByTagName("img")[i].src="image4.jpg";
</script>
Le premier objet image a été désigné par son identifiant "im1". Les deux derniers ont été désignés par leur nom de balise (TagName) qui correspond évidemment à "img". Puisqu'il s'agit d'un tableau, alors on a précisé les indexes des objets à cibler entre les crochets.
L'oubli de s de getElementsByTagName() est une erreur très courante. Faites y attention! Il faut aussi s'assurer de la casse (majuscules et minuscules) lors de l'appel des objets.
Comme je l'ai signalé dans ce paragraphe, les deux dernière méthodes permettent d'accéder à tous les objets HTML du document déclarés entre <body> et </body>. Si on veut désigner l'objet (balise) <body> lui même alors on recourt à la syntaxe document.body (après tout, il n'y a qu'un seul body dans le document).

Après avoir ciblé nos objets, que pouvons nous faire à part changer la source des images et désigner une zone de texte?

Attribut innerHTML

Jusqu'ici, nous avons pu écrire des textes dans des champs de formulaire et des boites de dialogue. Mais si on veut écrire n'importe où dans la balise <body> alors on peut le faire grâce à l'attribut innerHTML.
Exemple:
<div id="contenu">Bonjour</div>
<script language="javascript">
   document.getElementById("contenu").innerHTML="Bonsoir";
</script>
Au chargement de la page, la balise <div> identifiée par contenu contient le texte "Bonjour". Une fois le script Javascript exécuté, le nœud texte "Bonjour" est remplacé par "Bonsoir" grâce à l'attribut innerHTML.
L'attribut innerHTML s'applique sur tous les objets HTML déclarés dans le body et qui peuvent accueillir du texte sauf les champs de formulaire sur lesquelles l'attribut value est appliqué.

Attribut className

L'attribut className renomme l'attribut class d'un élément. C'est pratique pour appliquer des styles CSS dynamiquement à l'objet en question.

Exemple:
<!DOCTYPE html>
<html>
   <head>
      <meta charset="UTF-8" />
      <style>
         .nouvelleClasse{
            color:#FFFFFF;
            font-size:18pt;
            background-color:#000000;
            padding:10px;
         }
      </style>
      <script language="javascript">
         function changer(){
            document.getElementsByTagName("h1").item(0).className="nouvelleClasse";
         }
      </script>
   </head>
   <body>
      <h1>Titre d'order 1</h1>
      <input type="button" value="Changer l'apparence" onclick="changer()" />
   </body>
</html>
Dans cet exemple, le fait de cliquer sur le bouton "Changer l'apparence" appelle la fonction changer() qui va renommer (ou créer) l'attribut classe en lui attribuant la valeur "nouvelleClasse". Par conséquent, les styles CSS définis pour cette classe seront appliqués au titre <h1>. Donc, par simple clic, le titre <h1> changera d'apparence.

Vous avez peut être remarqué .item(0). Elle a exactement le même rôle que [0]. Donc vous choisissez l'un ou l'autre car ils font la même chose: désigner l'indexe de l'élément ciblé. N'oubliez pas le point avant item.

Sous-objet style

Le sous-objet style permet de définir dynamiquement un attribut de style local style sur la balise concernée.

Exemple:
<span id="citation">
   Mieux vaut tard que jamais.
</span>
<script language="javascript">
   document.getElementById("citation").style.color="#888888";
   document.getElementById("citation").style.fontStyle="italic";
</script>
Je crois que vous avez compris l'astuce. Les attributs du sous-objets style sont les propriétés que nous avons déjà vu en CSS. Si la propriété est composée, alors le tiret et enlevé et le caractère immédiatement suivant est capitalisé. Par exemple font-style devient fontStyle et text-decoration devient textDecoration...

La valeur à appliquer à l'attribut est la même que celle que vous auriez déclarée en CSS, juste que cette fois, il faut la placer entre des guillemets, car elle est vue en Javascript en tant que chaîne de caractères.

Méthode setAttribute()

Si on veut changer dynamiquement la valeur d'un attribut d'une balise alors on fait appel à l'attribut setAttribute.

Exemple:
<div align="left">
   Contenu de la DIV.
</div>
<script language="javascript">
   document.getElementsByTagName("div").item(0).setAttribute("align","center");
</script>
L'attribut align avait comme valeur "left". Une fois le script exécuté, sa nouvelle valeur devient "center". La méthode setAttribute accepte deux paramètres; le premier est le nom de l'attribut à modifier, le second est la valeur qu'on souhaite lui attribuer.

La méthode setAttribute peut changer la valeur de tous les attributs des balises du body y compris les classes et les attributs de style local.
Exemple 1:
// Au lieu de
document.getElementsByTagName("h1").item(0).className="nouvelleClasse";

// On peut mettre
document.getElementsByTagName("h1").item(0).setAttribute("class","NouvelleClasse");
Exemple 2:
// Au lieu de
document.getElementsByTagName("h1").item(0).style.color="red";

// On peut mettre
document.getElementsByTagName("h1").item(0).setAttribute("style","color:red");
Cependant, dans l'exemple 2 il est préférable d'utiliser la première syntaxe.

Méthode getAttribute()

La méthode getAttribute permet de récupérer la valeur de l'attribut passé en paramètre.

Exemple:
<video src="pub.ogv" id="publicite"></video>
<script language="javascript">
   alert(document.getElementById("publicite").getAttribute("src"));
</script>
L'exécution de scripte entraîne l'affichage de "pub.ogv" dans la boite de dialogue alert().