Disposer en mémoire vive d'une représentation en arbre d'un document
Définir comment modifier cet arbre de façon unifiée pour tous les navigateurs
Page web vue = Représentation graphique de l'arbre
Changement de l'arbre ⇒ changement de la vue
Document Object Model : spécification du WhatWG et norme du W3C
Nécessité du DOM
Les programmes en JavaScript sont exécutés par le navigateur
Leur but : modifier la page HTML/CSS en fonction des actions de l'internaute
Il faut donc avoir un modèle de la page et de sa structure, ainsi que des fonctions permettant de manipuler ce modèle : une API (application programming interface)
Le modèle des pages HTML (et XML) s'appelle le DOM, document object model
Langage utilisé dans les navigateurs : Javascript
Notions de DOM et fonctionnalités existantes dans d'autres langages (Python, Java, PHP, etc)
Historique du DOM
1996 : sortie de JavaScript avec Netscape 2.0 puis de JScript avec IE 3.0
Les deux versions ont un DOM majoritairement compatible, JScript étant un portage de JavaScript
On l'appelle souvent DOM niveau 0
1997 : Netscape et IE versions 4.0, développés en parallèle, introduisent des modifications incompatibles dans leurs DOM
Il fallait donc plusieurs versions de chaque programme pour une même page web…
1998 : Standardisation par le W3C du DOM niveau 1
DOM 2 en 2000, DOM 3 en 2004, DOM 4 en 2014
DOM Living Standard édité par le WhatWG unifie les anciennes normes et les implémentations existantes dans les navigateurs
HTML ⇒ DOM ⇒ Vue
Navigateur = parseur HTML + moteur graphique
Parseur HTML : construit l'arbre DOM en mémoire
Moteur graphique : construit une représentation de l'arbre DOM, suivant les règles données dans les CSS
Passage du HTML au DOM puis à la Vue
Modification du DOM
JavaScript : implémente l'API DOM ⇒ possibilité de transformer l'arbre
Toute modification de l'arbre DOM est immédiatement répercutée dans la représentation graphique
Attention : l'arbre DOM est modifié dans la mémoire du navigateur, mais « afficher le code source » montre toujours le code de départ !
Pour voir le code HTML correspondant à l'état réel du DOM à tout instant, utiliser l'inspecteur de Firefox ou Chrome
En général on ne manipulera pas directement le style : séparation entre
présentation (CSS) et comportement (JS)
La façon propre de faire est de passer par des classes, dont le style
est défini indépendamment du script
Pour manipuler les classes, on utilisera la propriété classList
des éléments (ne marche pas pour IE<10) :
toto = document.getElementById("toto");
toto.classList.add("tutu");
toto.classList.remove("titi");
if (toto.classList.contains("foobar"))
toto.classList.toggle("erreur");
Modifier le texte d'un nœud
Pour modifier le texte, par ex. d'un paragraphe,
on peut récupérer son nœud textuel et modifier son attribut nodeValue :
let para = document.querySelector("p");
alert(para.firstChild.nodeValue); // affiche le texte
para.firstChild.nodeValue = "nouveau texte !";
Pas très robuste, car le paragraphe peut contenir d'autres nœuds
(par ex. un élément em), auquel cas on ne remplace pas tout.
Solution plus simple : attribut textContent,
qui correspond au texte concaténé de tous les descendants du nœud
En modifiant textContent on remplace tous les descendants
du nœud par un unique nœud de texte
L'attribut innerHTML
Parfois on veut remplacer le contenu du nœud par d'autres nœuds
innerHTML fonctionne de la même façon que textContent,
mais en « gardant les éléments HTML »
Peut provoquer des failles de sécurité
(injections) et n'est pas très efficace
Très pratique pour les tests et les bidouilles rapides, mais :
interdiction de l'utiliser les TPs
Créer des branches de l'arbre DOM
On peut créer une branche d'arbre DOM
let newP = document.createElement("p");
let newTxt = document.createTextNode("contenu");
newP.appendChild(newTxt);
puis l'attacher comme fils à un nœud existant
let maDiv = document.getElementById("toto");
maDiv.appendChild(newP);
Créer des éléments avec des attributs
Les éléments que l'on crée n'ont aucun attribut,
il faut les ajouter explicitement
let monA = document.createElement("a");
monA.setAttribute("href", "http://example.com");
monA.setAttribute("title", "Exemple");
let monText = document.createTextNode("Le site example.com");
monA.appendChild(monText);
maDiv.appendChild(monA);
Autres manipulations
Supprimer un fils : papa.removeChild(toto)
Insérer un fils avant un autre : papa.insertBefore(nouveau, toto)
Cloner un nœud : toto.cloneNode(true)
le paramètre indique qu'on veut cloner le nœud avec tous ses descendants
(c'est généralement ce qu'on veut)
attention, il faut attacher le nouveau nœud dans l'arbre ensuite)
Remplacer un fils par un autre : papa.replaceChild(nouveau, toto)
Bilan de cours
Le DOM permet :
de construire une représentation en arbre d'un document
d'offrir une interface commune d'accès et modification du document, quelque soit le langage applicatif
Grâce à l'implémentation de l'interface DOM dans le langage JavaScript, nous pouvons directement dans le navigateur :
repérer un élément dans l'arbre DOM
modifier ses attributs, notamment ses classes, pour modifier son apparence