Introduction
Un document XML ou HTML peut être vu sous la forme d'un arbre:
DOM est conçu pour XML de façon générique, et comporte des objets dédiés à HTML. Il s'agit d'un modèle abstrait, indépendant du langage :
- Spécification officielle en IDL
- Interfaces officielles pour Java et ECMAScript
- Implémentations pour Java, JavaScript (navigateurs),
- et presque tous les autres langages
Il s'agit d'une approche objet du modèle d'arbre: Chaque nœuds est un objet, et des méthodes permettent d'accèder aux noeuds en relation avec un noeud donné.
Les principaux types de nœuds sont:
- Document: la racine
- Element: les balises standards
- Text: le... texte
- Comment: les commentaires
- Attr: les attributs des balises
- Processing instructions: les balises spécifiques comme par exemple
<?php...?>
La navigation dans l'arbre se fait en appelant:
- le parent d'un noeud
- les fils d'un noeud (child)
- les attributs d'un noeud
- les noeud-frères (sibling)
DOM en Javascript
Lorsqu'une page internet se charge, un objet particulier est créé:
l'objet window.document
. Il propose en particulier des « raccourcis »
pour accéder à certains éléments d'une page web.
Attention: L'objet document n'est disponible qu'une fois que la page est complètement chargée, après l'événement load (voir le tuto qui parle de la gestion des évènements).
A partir du nœud « window.document » :
- window.document.head : élément <head>
- window.document.title : élément <title>
- window.document.body : élément <body>
Et aussi:
- window.document.images : collection d'éléments <img>
- window.document.links : collection d'éléments <a>
- window.document.forms : collection d'éléments <form>
Par exemple, si avec Firefox depuis cette page vous lancez la console javascript (Ctrl+Shift+K
) et que vous exécutez:
la console doit vous répondre :
c'est à dire le titre de la page à comparer avec ce qu'il y a dans le source (Ctrl+U
pour y accèder).
Exploration générique de l'arbre
Sur n'importe quel nœud « n », on peut obtenir son nom et son type:
- n.nodeName : chaîne de caractères
- n.nodeType : entier (1: élément, 2: attribut, 3: texte, … voir la liste complète)
- n.nodeValue : chaîne de caractères (pour nœuds attributs et texte)
Mais aussi ses attributs:
- n.hasAttributes() : booléen
- n.attributes : collection ordonnée des attributs (se traite comme un tableau)
Sa relation verticale dans l'arbre:
- n.parentNode : objet
- n.hasChildNodes() : booléen
- n.childNodes : collection ordonnée des noeuds fils (se traite comme un tableau)
- n.firstChild : objet
- n.lastChild : objet
Et sa relation parallèle dans l'arbre:
- n.previousSibling : objet
- n.nextSibling : objet
On peut enfin savoir quel est le window.document racine de l'arbre:
- n.ownerDocument : objet
Exemple
Ouvrez la page exemple.html dans firefox, et
- ouvrez la console (
Ctrl+Shift+K
dans firefox) - ouvrez le source de la page (
Ctrl+U
): - ouvrez le scratchpad javascript (
Shift+F4
)
Que donne les instructions ? (Attention, il faut que le focus de la fenêtre soit bien sur la page à considèrer, donc exemple.html), et pas sur son code soure, quand vous faites la manip).
- Le noeud commentaire est parmis les fils du noeud body: quel est son index dans la liste ?
- Quelle valeur rend nodeType sur le commentaire ?
- Pouvez-vous afficher le texte de la deuxième balise
<h1>
dans la console ? - Notez comme les espaces entre les balises forment bien des noeuds textes.
Recherche dans l'arbre
On peut rechercher des éléments et des attributs:
Éléments
À partir du noeud document, peut chercher un élément par son attribut id
À partir d'un noeud quelconque, on peut rechercher dans son sous-arbre
un ensemble (ordonné) d'éléments filtré par le nom de leur balise. Par
exemple, dans l'exemple précédant, si on place dans le scratchpad:
on récupère les deux noeuds <h1>
et on peut directement afficher leur texte.
Attributs
A partir d'un nœud de type élément « e » :
- e.id : chaîne de caractères (si l'élément a un id...)
et de façon générale:
- e.hasAttribute(name) : booléen
- e.getAttribute(name) : chaîne de caractères
On peut aussi modifier les attributs d'un noeud:
- e.setAttribute(name, value)
- e.removeAttribute(name)
Dans l'exemple précédant, comme on sait récupérer les éléments correspondant aux balises <h1>
, on peut leur mettre de la couleur en leur ajoutant un attribut style
bien choisi:
Si cela ne nous convient pas:
Modification de l'arbre
Outre l'ajout et la suppression d'attribut, l'interface DOM permets de rajouter ou de supprimer des noeuds quelconques.
L'ajout d'un noeud se fait en deux temps:
- fabrication du noeud
- puis quand il est prêt, insertion dans l'arbre DOM.
La suppression d'un noeud se fait directement, bien sûr.
Création de noeuds
Comme ces noeuds seront dans l'arbre dont la racine est le noeud document, toutes ces fonctions sont des méthodes de window.document. On trouve en particulier:
- window.document.createElement(tagName) : retourne l'élément créé
- window.document.createElementNS(namespaceURI, tagName) : pour fixer un espace de nom à l'élément ; retourne l'élément créé
- window.document.createTextNode(text) : retourne le nœud texte créé
- window.document.createComment(text) : retourne le nœud commentaire créé
- window.document.createAttribute(name) : retourne le nœud attribut créé
Modification de l'arbre DOM
On peut ensuite placer ces noeuds comme fils ou noeuds-frères dans l'arbre. Si "n" est n'importe quel noeud:
- n.removeChild(nodeToRemove) : retourne l'objet supprimé
- n.insertBefore(nodeToInsert, childRef) : retourne l'objet inséré
- n.appendChild(nodeToAppend) : retourne l'objet inséré
- n.replaceChild(newNode, oldNode) : retourne l'objet remplacé
- n.cloneNode(deepOrNot) : retourne l'objet résultat de la copie
Exemple
Création d'un noeud <h1>
Que se passe-t-il si vous appliquez ces instructions dans le scratchpad de l'exemple du dessus ?
Conclusion
JavaScript + DOM = pages web dynamiques !
Plus loin? nous verrons ensuite comment Jquery facilitera énormément l'écriture de vos programmes JavaScript ! Nous verrons aussi comment utiliser javascript coté serveur.
Petits bémols :
- Il est possible de faire n'importe quoi en JavaScript... Trop de JavaScript tue le JavaScript !
- Il peut y avoir des problèmes de compatibilité entre navigateurs (JS & DOM)