Le modèle objet du document (DOM)

Le modèle objet du document (Document Object Model ou DOM) est la représentation par des objets d'une page WEB: le document en terme de JavaScript.  Il permet, par programmation, de manipuler le contenu du document d'une manière structurée et orientée objet.  Il possède plusieurs méthodes pour accéder aux divers objets, changer leurs propriétés, en ajouter ou en détruire.

Les niveaux du DOM

Au début de JavaScript on utilisait quelques structures simples pour représenter les objets d'un document.  Par exemple l'objet «document.images» est un tableau contenant les images d'un document.  C'est maintenant ce qu'on appelle le DOM de niveau 0.  En 1998, le World Wide Web Consortium, adopta le standard DOM1 de représentation pour les documents WEB. 

La plupart des navigateurs modernes (version 5 et plus) supporte le standard DOM2 adopté à la fin de l'an 2000 par le W3C.  Le DOM2 s'applique à XML mais comme HTML peut être vu comme un sous-ensemble de XML, il est possible de l'utiliser.  Le W3C travaille actuellement sur le DOM3.

Le DOM est donc un standard qui sert d'interface entre le XML (ou HTML en ce qui nous concerne) et JavaScript.  Il dépend donc indirectement des standards du HTML et du CSS en plus du standard du XML.

Représentation hiérarchique du document

Les navigateurs, au moment du chargement d'une page, construisent une structure arborescente sous forme de noeuds représentants les éléments, les attributs, le texte et autres.

Les nœuds

Les différents objets possèdent leurs propres propriétés et leur propres méthodes en plus d'un ensemble commun pour manipuler la structure elle-même.  Voici une représentation générale:

L'objet «nœud» a plusieurs propriété qui reflète cette structure et qui permettent de parcourir l'arbre.  Par exemple:

L'objet «nœud» possède aussi des méthodes qui permettent de modifier la structure elle-même comme par exemple:

La racine du document

La racine de l'arborescence est l'objet «document» qui implante aussi l'interface des nœuds.  Il possède des nœuds enfants mais pas de parent ou de frères puisqu'il est le tronc de l'arbre.  L'objet «document» implante aussi l'interface "document" qui permet d'accéder aux divers nœuds et d'en créer.

Pour des raisons de compatibilité l'objet «document» possède aussi les propriétés et les méthodes du DOM0 (document.images, document.links, document.bgColor, document.write, ...).

 

Parcours de l'arborescence

Dans une page HTML chaque élément est représenté par des nœuds éléments ainsi que des nœuds attributs et le texte est représenté par des nœuds de texte.

Techniquement, l'objet «document» a un seul descendant: l'objet «document.documentElement» qui correspond au conteneur <HTML>...</HTML>.  Cet objet a deux descendants: <HEAD> et <BODY>.  Voici un premier exemple.

Cette façon d'accéder aux noeuds présente toutefois des problèmes.  Le code dépend directement de la structure du document.  L'exemple suivant permet de visualiser les éléments d'un document à l'aide du fameux DOM Viewer de BrainJar.com.

 

Accès direct aux éléments

Si on a la bonne idée d'identifier nos éléments à l'aide de l'attribut ID, la méthode getElementById() nous permettra d'accéder directement à tout élément.  N'oubliez pas que vos identificateurs doivent être unique.  Le troisième exemple illustre l'utilisation de cette méthode.

Nous pouvons aussi utiliser la méthode getElementByTagName() pour obtenir la liste complète de tous les éléments d'un même type.  Voir cet exemple.  Ou alors getElementByName() pour avoir la liste de tous les éléments du même nom.

 

Les types de noeuds

Il existe plusieurs types de noeuds dans le DOM mais en ce qui concerne le HTML seulement trois sont utilisés:

Les noeuds éléments

Ces noeuds représentent les éléments d'une page Web.  Ils peuvent avoir des descendants qui seront ou bien des noeuds éléments ou alors des noeuds de texte.

Les noeuds de texte

Ces noeuds correspondent au texte lui-même.  Ils ont un parent et possiblement des noeuds frères mais pas de descendant.

Les noeuds attribut

Ce sont des noeuds spéciaux.  Il ne font pas partie de l'arborescence du document comme tel et ne sont là que pour représenter les divers attributs des noeuds élément.  Ils n'ont ni parent, ni frères ni enfants.  Ce sont des chaînes de texte.  Pour gérer ces attributs nous avons les méthodes suivantes:

On peut aussi accéder aux attributs au moyen de la notation classique: noeud.nom_de_l'attribut.

Les attributs de style

Comme les attributs de style sont plus complexe que les autres le DOM défini la propriété style que possède tout noeud élément.  Je vous ai concocté un petit exemple.

 

Le dynamisme du DOM

Non seulement le DOM nous permet-il de modifier les attributs et les attributs de style mais aussi le contenu du document.

Les noeuds de texte

La propriété nodeValue des noeuds de texte permettent d'accéder et de modifier le texte lui-même.  Comme nous ne pouvons pas identifier (ID) les chaînes de caractères nous devrons passer par leur noeud parent.  Soyez conscient que les noeuds de texte ne contiennent que du texte brut.  Toutes balises HTML générera un noeud supplémentaire.  Voici encore un exemple.

Si vous désirez inclure du HTML il sera alors préférable d'utiliser la propriété innerHTML du noeud.  Soyez toutefois informé que cette propriété, bien que supportée par les navigateurs modernes ne fait pas partie du standard DOM2.

 

Ajout de noeuds

En plus de modifier le contenu des noeuds de texte il est possible d'ajouter ou de détruire des noeuds éléments.  Dans un premier temps il faudra créer le noeud et ensuite le rattacher à la structure du document.  Pour créer les noeuds nous utiliserons les méthodes suivantes:

ensuite nous pourrons insérer (ou détruire) les nouveaux noeuds à l'aide de:

 

Les noeuds de texte et la normalisation

Lorsqu'on ajoute des noeuds de texte à un parent ceux-ci sont considérés comme indépendants.  Si vous désirez regrouper les noeuds de texte et détruire les noeuds vides vous pouvez utiliser la méthode normalize().  Il est aussi possible de séparer un noeud de texte en deux parties avec la méthode splitText().  Un exemple vaut mille mots.

 

Les noeuds élément

La création des noeuds éléments fonctionnent comme celle des noeuds de texte sauf qu'en plus il faut placer du contenu à l'intérieur.  Voici un exemple et un autre plus complexe.

 

Autres exemples intéressants

 

Propriétés, méthodes et événements de tous les éléments

Les propriétés

element.attributes Tableau des attributs de l'élément
element.childNodes Tableau des noeuds enfants de l'élément
element.className Classe de l'élément
element.dir Direction de l'élément (ltr ou rtl)
element.firstChild Le premier descendant de l'élément
element.id Identificateur (ID) de l'élément
element.innerHTML Le contenu HTML de l'élément
element.lang L'attribut LANG de l'élément
element.lastChild Le dernier descendant de l'élément
liste.length Le nombre de valeurs dans une liste (tableau)
element.localName La partie locale d'un noeud qualifié (pour XML)
element.namespaceURI L'espace de noms URI pour l'élément ou NULL si non spécifié (pour XML)
element.nextSibling Le noeud suivant de l'élément
element.nodeName Le nom de l'élément
element.nodeType Le type de l'élément (voir tableau suivant)
element.nodeValue La valeur de l'élément
element.offsetHeight Offset en pixels par rapport au offsetParent
element.offsetLeft Position horizontale en pixels par rapport au parent
element.offsetParent Le parent de l'élément
element.offsetTop Position verticale en pixels par rapport au parent
element.offsetWidth Offset en pixels par rapport au parent
element.ownerDocument Le document auquel appartient l'élément
element.parentNode Le noeud parent
element.prefix Le préfixe de l'espace de noms ou NULL si non spécifié (pour XML)
element.previousSibling Le noeud précédent
element.style Le bloc de règles de style
element.tabIndex L'ordre de tabulation (pour les formulaires)
element.tagName Le nom HTML (ou XML) de l'élément
element.title Le titre de l'élément

Les types d'éléments

ELEMENT_NODE 1
ATTRIBUTE_NODE 2
TEXT_NODE 3
CDATA_SECTION_NODE 4
ENTITY_REFERENCE_NODE 5
ENTITY_NODE 6
PROCESSING_INSTRUCTION_NODE 7
COMMENT_NODE 8
DOCUMENT_NODE 9
DOCUMENT_TYPE_NODE 10
DOCUMENT_FRAGMENT_NODE 11
NOTATION_NODE 12

Les méthodes

element.addEventListener(type, fonction, useCapture) Enregistrement d'un gestionnaire d'événement
element.appendChild(noeud) Ajoute un noeud enfant à l'élément
element.blur() Enlève le focus à l'élément
element.click() Provoque un événement CLICK sur l'élément
element.cloneNode(complete) Retourne une copie de l'élément complète ou non
element.dispatchEvent(event) Permet la production d'un événement
element.focus() Donne le focus à l'élément
element.getAttribute(nom) Retourne un attribut de l'élément
element.getAttributeNS(namespace, nom) Retourne un attribut dans un espace de noms
element.getAttributeNode(nodeName) Retourne un noeud attribut de l'élément
element.getElementByTagName(nom) Retourne la liste des enfants d'un type HTML donné
element.hasAttribute(attName) Si un élément a un attribut donné
element.hasAttributeNS(namespace, nom) Si un élément a un attribut donné dans un espace de noms
element.hasChildNodes() Si l'élément a des enfants
inserted = element.insertBefore(new, target) Ajoute un noeud avant l'élément
element.item(index) Retourne un noeud par son index dans une liste
element.normalize() Normalisation de l'élément et de ses descendants
element.removeAttribute(attName) Enlève un attribut à l'élément
element.removeAttributeNode(attNode) Enlève un noeud attribut à l'élément
old = element.removeChild(child) Enlève un enfant à l'élément
element.removeEventListener(type, fonction, useCapture) Enlève un gestionnaire d'événements
element.replaceChild(new, old) Remplace un enfant de l'élément par un autre
element.setAttribute(nom, valeur) Ajoute un attribut à l'élément
element.setAttributeNS(namespace, nom, valeur) Ajoute un attribut à l'élément dans un espace de noms
attr = element.setAttributeNode(attrNode) Ajoute un noeud attribut à l'élément
bool = element.supports(feature, version) Vérifie si le DOM supporte une certaine fonctionnalité

Les événements

element.onblur Retourne le code pour l'événement BLUR
element.onclick Retourne le code pour l'événement CLICK
element.ondblclick Retourne le code pour l'événement DBLCLICK
element.onfocus Retourne le code pour l'événement FOCUS
element.onkeydown Retourne le code pour l'événement KEYDOWN
element.onkeypress Retourne le code pour l'événement KEYPRESS
element.onkeyup Retourne le code pour l'événement KEYUP
element.onmousedown Retourne le code pour l'événement MOUSEDOWN
element.onmouseout Retourne le code pour l'événement MOUSEOUT
element.onmouseover Retourne le code pour l'événement MOUSEOVER
element.onmouseup Retourne le code pour l'événement MOUSEUP
element.onresize Retourne le code pour l'événement RESIZE

 

L'interface Window

Les propriétés

window._content Référence à l'élément "content" d'une fenêtre
window.closed Si la fenêtre est fermée
window.Components Composantes installées dans le navigateur
window.controllers Contrôleur XUL pour la fenêtre
window.crypto L'objet CRYPTO du navigateur
...

Les méthodes

Les événements

 

L'interface Document

Les propriétés

Les méthodes

Les événements

 

L'objet Event

Les propriétés

Les méthodes

 

Les styles

 

Les formulaires

 

L'objet Range

 

 

En résumé

Propriétés, collections et méthodes Description
document.createElement('NOM') Créé un élément de type NOM et retourne l'objet
document.createTextNode('texte') Créé un élément de type TEXTE et retourne l'objet
document.body Le conteneur BODY
document.documentElement Le conteneur HTML
document.getElementById('ID') Retourne l'élément dont l'identificateur est ID
document.getElementByTagName('NOM') Retourne la liste des éléments de type NOM
document.styleSheets[] Liste des feuilles de style du document
<noeud>.childNodes[] Liste des fils d'un noeud
<noeud>.parentNode Le parent du noeud en question
<noeud>.firstChild Le premier fils du noeud
<noeud>.getElementById('ID') Retourne l'élément dont l'identificateur est ID
<noeud>.getElementByTagName('NOM') Retourne la liste des éléments de type NOM
<noeud>.lastChild Le dernier fils du noeud
<noeud>.nextSibling L'entrée suivante dans la liste des fils du noeud parent
<noeud>.previousSibling L'entrée précédente dans la liste des fils du noeud parent
<noeud>.appendChild(<noeud>) Ajoute un noeud à la liste des fils.
<noeud>.cloneNode(<noeud>) Retourne une copie d'un noeud
<noeud>.innerHTML Le contenu d'un noeud
<noeud>.insertBefore(<noeud>1, <noeud>2) Insère le <noeud>1 avant le <noeud>2
<noeud>.removeChild(<noeud>) Détruit le fils en question
<noeud>.replaceChild(<noeud>1, <noeud>2) Remplace le <noeud>1 par le <noeud>2
<noeud>.splitText(index) Sépare le texte en deux noeuds à partir de l'index spécifié
<noeud>.data Contenu d'un noeud de texte
<noeud>.hasChildNodes() Si le noeud a des fils
<noeud>.id L'ID d'un noeud
<noeud>.nodeName Type de noeud ('#text' pour un noeud de texte)
<noeud>.nodeType
  1. pour un élément HTML
  2. pour un attribut (ou undefined)
  3. pour un noeud de texte
<noeud>.nodeValue Le texte pour un noeud de texte ou l'attribut pour un noeud attribut
<noeud>.offsetLeft Position horizontale du noeud
<noeud>.offsetTop Position verticale du noeud
<noeud>.specified Est-ce que le noeud est en lecture seulement?
<noeud>.tagName Nom (Élément HTML) du noeud (en majuscules)
<noeud>.title L'attribut TITLE du noeud
<noeud>.attributes[] Liste des attributs du noeud
<noeud>.getAttribute('ATTR') Valeur de l'attribut ATTR du noeud
<noeud>.removeAttribute('ATTR') Élimination de l'attribut
<noeud>.setAttribute('ATTR', 'valeur') Création d'un attribut
<noeud>.className Classe du noeud
<noeud>.style Les styles du noeud
<noeud>.caption "Caption" pour un noeud TABLEAU
<noeud>.cells[] Liste des cellules d'un noeud TR
<noeud>.rows[] Liste des lignes d'un noeud THEAD, TBODY, etc
<noeud>.tBodies[] Liste des TBODY d'un tableau
<noeud>.tFoot Le noeud TFOOT d'un tableau
<noeud>.tHead Le noeud THEAD d'un tableau
<noeud>.deleteCell(index) Élimination d'une cellule
<noeud>.deleteRow(index) Élimination d'une ligne
<noeud>.deleteTFoot() Élimination du TFOOT d'un tableau
<noeud>.deleteTHead() Élimination du THEAD d'un tableau
<noeud>.cellIndex Index d'une cellule (pour un TH ou un TD)
<noeud>.rowIndex Index d'une ligne dans TBODY, THEAD ou TFOOT