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.
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.
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 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:
(Noeud1).firstChild = Noeud1.1
(Noeud1).lastChild = Noeud1.3
(Noeud1).childNodes.length = 3
(Noeud1).childNodes[1] = Noeud1.2
(Noeud1.1).parentNode = Noeud1
(Noeud1.2).nextSibling = Noeud1.3
(Noeud1.2).prevSibling = Noeud1.1
(Noeud1.2.2).nextSibling = null
(Noeud1.2.1).parentNode.parentNode = Noeud1
L'objet «nœud» possède aussi des méthodes qui permettent de modifier la structure elle-même comme par exemple:
insertBefore()
replaceChild()
cloneNode()
removeChild()
appendChild()
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, ...).
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.
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.
Il existe plusieurs types de noeuds dans le DOM mais en ce qui concerne le HTML seulement trois sont utilisés:
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.
Ces noeuds correspondent au texte lui-même. Ils ont un parent et possiblement des noeuds frères mais pas de descendant.
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.
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.
Non seulement le DOM nous permet-il de modifier les attributs et les attributs de style mais aussi le contenu du document.
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.
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:
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.
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.
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 |
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 |
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é |
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 |
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 |
... |
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 |
|
<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 |