Quand un document structuré est chargé, XML ou HTML, le navigateur crée le DOM (Document Object Model), une représentation orientée objet de la page. Exemple de page HTML:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Simple DOM example</title>
</head>
<body>
<section>
<img src="dinosaur.png" alt="A red Tyrannosaurus Rex: A two legged dinosaur standing upright like a human, with small arms, and a large head with lots of sharp teeth.">
<p>Here we will add a link to the <a href="https://www.mozilla.org/">Mozilla homepage</a></p>
</section>
</body>
</html>
Et son DOM associé:
Chaque balises et contenu texte du document est un noeud dans le DOM. Il existe différents termes pour décrire le type de noeud et sa position dans l’arbre du DOM par rapport à un autre. Il est utile de connaitre ces termes, puisqu’ils sont souvent utilisés dans les documentations.
Terme | Terme anglais | Rôle |
---|---|---|
Element | Element | N'importe quel élément, tel qu'il existe dans le DOM |
Texte | Text | Noeud constitué par une chaîne de caractère |
Racine | Root | La racine est le noeud de plus haut niveau dans le DOM. Dans le cas d'un document HTML, la racine est l'élément <html> (d'autres langages de balisage tels que SVG et XML auront es racines différentes). |
Enfant | Child | Un enfant est un noeud situé à l'intérieur d'un autre noeud, niveau+1.<body> est l'enfant de <html>
|
Descendant | Descendent | Un descendant est noeud situé à l'intérieur d'un autre noeud, niveau+n.<section> est un descendant de <html> mais pas son enfant |
Parent | Parent | Le parent d'un noeud est le noeud qui le contient, niveau-1.<body> est le parent de <section>
|
Ancêtre | Ancestor | Un ancêtre d'un noeud est le noeud qui le contient, niveau-n.<html> est un ancêtre de <section>
|
Frère | Sibling | Un frère d'un noeud est un noeud qui a le même parent.<img> est le frère de <p> . |
Le contenu de la page est stocké dans le DOM et on peut y accéder/le manipuler via JavaScript grâce à une API - l’API DOM. L’API DOM définit un ensemble de méthodes et propriétés sur les éléments du DOM, selon le type de l’élement. Cela peut permettre par exemple de lire ou modifier du contenu.
Le noeud de plus haut niveau de la page, la racine, est contenue dans l’objet global document
.
On utilise cet objet pour pouvoir accéder à tout élément dans la page.
Par exemple, pour changer le contenu de l’élément ayant l’id “paragraph”:
document.getElementById("paragraph").textContent = "Bonjour tout le monde";
ou
document.getElementById("paragraph").innerHTML = "<strong>Bonjour</strong> tout le monde";
Notez que le DOM est crée est fur et à mesure du chargement de la page. Il est conseillé de n’y accéder qu’une fois la page complètement chargée, et ce afin que le DOM soit entier.
window.onload = function(){
// Accéder au DOM une fois la page chargée
}
Il existe différentes méthodes pour sélectionner un élément:
document.getElementById(id) |
---|
Récupère l'élément avec l'id donné. Retourne un HTMLElement ou null.
|
element.getElementsByTagName(name) |
Récupère la liste d'éléments du tag donné. Retourne un HTMLCollection (un objet array-like). Peut être appelé sur `document` ou sur un HTMLElement.
|
element.getElementsByClassName(className) |
Récupère la liste d'éléments avec la classe donnée. Retourne un HTMLCollection. Peut être appelé sur `document` ou sur un HTMLElement.
|
element.querySelector(selector) |
Récupère le premier élément qui correspond au sélecteur donné (sélecteur CSS). Retourne un HTMLElement ou null. Peut être appelé sur `document` ou sur un HTMLElement.
|
element.querySelectorAll(selector) |
Récupère la liste d'éléments qui correspondent au sélecteur donné (sélecteur CSS). Retourne un HTMLCollection. Peut être appelé sur `document` ou sur un HTMLElement.
|
L’accès au DOM est très lent par rapport aux autres instructions JavaScript.
Si vous prévoyez d’accéder à un même élément à de multiples reprises, mieux vaut le sélectionner une seule fois en l’assignant à une variable locale, puis utiliser l’élément en mémoire pour effectuer des modifications.
var element = document.getElementById("myid"),
url = element.getAttribute('data-url');
element.setAttribute('src', url);
element.removeAttribute('data-url');
Il existe différentes propriétés et méthodes pour accéder et modifier les valeurs d’un HTMLElement.
On peut définit le texte d’un élément avec la propriété textContent
(le HTML est échappé)
element.textContent = "Mon texte"
Ou directement le HTML avec la propriété innerHTML
.
element.innerHTML = "Mon <strong>HTML</strong>"
On peut récupérer la valeur d’un attribut, en définir de nouveaux ou changer leur valeur, ou encore en supprimer.
// Récupérer la valeur
element.getAttribute('id')
// Définit la valeur
element.setAttribute('id', 1)
// Supprimer l'attribut
element.removeAttribute('id')
Plutôt que d’utiliser les méthodes getAttribute
, etc, on peut récupérer/définir les styles d’un élément - individuellement - avec la propriété style
:
element.style.left = '12px';
Les propriétés CSS composées s’écrivent avec la norme camelCase en JavaScript.
Par exemple font-family
devient fontFamily
.
element.style.lineHeight = '30px';
De même, on peut utiliser la propriété classList
pour récupérer la liste des classes de l’élément (objet DOMTokenList) et ainsi vérifier la présence d’une classe, ajouter, supprimer ou remplacer une classe.
element.classList.contains('myclass')
element.classList.add('newclass')
element.classList.remove('oldclass')
element.classList.replace('oldclass', 'newclass')
La valeur de l’attribut class
(chaîne de caractères) peut être récupérée avec la propriété className
. C’est un raccourci pour getAttribute("class")
.
element.className
HTML5 permet d’associer des données à un élément HTML à l’aide des attributs data-*.
La propriété dataset
permet de récupérer et modifier ces valeurs
// Définir une métadonnée
element.dataset.prop = "test";
// Récupérer une métadonnée
console.log(element.dataset.prop);
Ce qui revient à
console.log(element.getAttribute("data-prop"));
Pour créer un élément, on utilise la méthode createElement(tagName)
.
Une fois l’élément créé, on peut modifier ses attributs et son contenu avant de l’ajouter au DOM - moment où il devient visible à l’écran. Par exemple, pour ajouter un nouveau paragraphe à <body>
:
var element = document.createElement('p'); // crée un paragraphe
element.textContent = "Bonjour tout le monde"; // change le contenu du paragraphe
document.body.appendChild(element); // ajoute l'élément nouvellement créé au DOM
Pour changer le parent d’un élément, on urilise la méthode appendChild(element)
sur le parent désiré.
Cela permet d’ajouter un élément nouvellement crée au DOM ou bien de déplacer un élément pré-existant dans la page.
var element = document.getElementById("myid"),
newParent = document.getElementById("footer");
newParent.appendChild(element);
Les méthodes de l’API DOM présentées ci-dessous sont les méthodes les plus couramment implémentées. Cependant, tous les navigateurs ne supportent pas tous les mêmes méthodes et notamment les anciens navigateurs.
Pour le support d’anciens navigateurs, on utilise souvent des librairies. De cette manière, on n’a plus besoin de savoir si tel ou tel navigateur implémente telle ou telle méthode, mais uniquement à utiliser les fonctions de la librairie. La plus connue est sans aucun doute JQuery.