Browser APIs

Le DOM

Le Document Object Model est le pont entre votre HTML et votre JavaScript. Apprenez à sélectionner, créer, mettre à jour et supprimer des éléments, et à répondre aux actions des utilisateurs.

beginner15 min readUpdated 15 sept. 2026
js
const list = document.querySelector("#todos");
const input = document.querySelector("#todo-input");

function addTodo(text) {
  const li = document.createElement("li");
  li.textContent = text;
  list.append(li);
}

input.addEventListener("keydown", (event) => {
  if (event.key === "Enter") {
    addTodo(input.value);
    input.value = "";
  }
});
Qu'est-ce que c'est
Un arbre d'objets dynamique
Construit par
Le navigateur, à partir de votre HTML
Sélection avec
querySelector / querySelectorAll
Réaction avec
addEventListener
Création avec
document.createElement
Coût
Travail de layout et de paint

Pratique

Essayer la manipulation du DOM

Cliquez sur le bouton, puis modifiez le code pour voir comment l'arbre change.

Essayer la manipulation du DOM

Cliquez sur le bouton, puis modifiez le code pour voir comment l'arbre change.

Pourquoi c'est important

Pourquoi le DOM est essentiel

Votre HTML, sous forme d'objets

Le navigateur analyse le balisage pour créer un arbre de nœuds que votre code peut lire et modifier à tout moment.

Retour instantané

Mettez à jour l'arbre et le navigateur redessine automatiquement la page — sans rechargement, sans aller-retour vers le serveur.

Réagissez à tout

Clics, saisies, défilements, redimensionnements, événements réseau et plus encore arrivent via un modèle d'événements unique.

Le tableau complet

Les trois concepts clés du DOM

Chaque tâche liée au DOM est une combinaison de trois actions : trouver un élément, le modifier ou réagir à un événement.

L'arbre

Structure

Une hiérarchie de nœuds où chaque élément, attribut et fragment de texte a une place et un parent.

La sélection

Trouver & modifier

Interrogez l'arbre, puis lisez ou écrivez du texte, des attributs, des classes et des styles sur les nœuds trouvés.

Les événements

Réagir

Écoutez les événements de l'utilisateur et du navigateur, puis exécutez du code en réponse — idéalement via la délégation.

Le DOM en un coup d'œil

Ce que vous pouvez faire avec le DOM

Sélectionner des éléments

querySelector retourne la première correspondance, querySelectorAll retourne toutes les correspondances sous forme de liste statique.

Lecture et écriture

textContent, innerHTML, les attributs et dataset vous permettent d'inspecter et de mettre à jour le contenu.

Classes et styles

classList et la propriété style modifient l'apparence sans toucher à une feuille de style.

Construction de nœuds

createElement, append, prepend et remove permettent de faire croître ou réduire l'arbre à la demande.

Événements

addEventListener s'abonne aux clics, aux entrées, au clavier, au défilement et bien plus encore.

Délégation d'événements

Un seul écouteur sur un parent peut gérer les événements de tous ses enfants, même ceux ajoutés ultérieurement.

Un bref aperçu

L'évolution du DOM

  1. 1996

    Le premier DOM

    Netscape et Microsoft proposent des méthodes concurrentes pour scripter les pages, lançant la première guerre des navigateurs.

    96
  2. 1998

    DOM Level 1

    Le W3C standardise un modèle d'arbre commun et une API partagée pour le manipuler.

    98
  3. 2009

    L'arrivée de querySelector

    Les sélecteurs de style CSS rendent la recherche d'éléments radicalement plus simple et expressive.

    09
  4. 2015

    classList et APIs modernes

    classList, dataset et template simplifient le travail quotidien sur le DOM et remplacent les anciens hacks.

    15
  5. Aujourd'hui

    Un standard vivant

    Le DOM est maintenu comme une spécification mise à jour en continu avec un large consensus entre navigateurs.

    Aujourd'hui

Le guide complet

Le DOM: Tout ce que vous devez savoir

Qu’est-ce que le DOM ?

Lorsque le navigateur lit votre HTML, il ne conserve pas une simple chaîne de texte. Il construit un arbre d’objets appelé le Document Object Model. Chaque élément devient un nœud avec des propriétés et des méthodes, chaque attribut est accessible et chaque fragment de texte a sa place. Le DOM est cet arbre, et il est dynamique : modifiez-le et la page se met à jour.

C’est pourquoi JavaScript et HTML semblent connectés. Votre HTML décrit la structure, le navigateur la transforme en objets, et JavaScript manipule ces objets. L’objet document est le point d’entrée de tout l’arbre.

L’arbre de nœuds

Le DOM est hiérarchique. Le document est la racine, <html> est son enfant, et tout le reste est suspendu en dessous selon une relation parent-enfant. Un nœud peut avoir plusieurs enfants, mais un seul parent.

document
└── html
    ├── head
    │   └── title
    └── body
        ├── h1
        └── p

Il existe plusieurs types de nœuds. Les nœuds d’élément représentent les balises. Les nœuds de texte contiennent les caractères à l’intérieur des éléments. Les nœuds de commentaire représentent les commentaires. La plupart du temps, vous travaillez avec des éléments, mais savoir que les nœuds de texte existent permet de comprendre les surprises liées aux espaces blancs et pourquoi childNodes peut inclure plus d’éléments que prévu.

Sélectionner des éléments

Avant de pouvoir modifier quoi que ce soit, vous devez d’abord le trouver. L’outil indispensable aujourd’hui est querySelector, qui accepte n’importe quel sélecteur CSS.

// select.js
const title = document.querySelector("h1");
const firstCard = document.querySelector(".card");
const allLinks = document.querySelectorAll("a[target='_blank']");
const byId = document.getElementById("main");

allLinks.forEach((link) => link.classList.add("external"));

querySelector renvoie le premier élément correspondant ou null. querySelectorAll renvoie une NodeList statique de toutes les correspondances, laquelle supporte forEach mais ne se met pas à jour lorsque le DOM change. Les anciennes méthodes getElementById, getElementsByClassName et getElementsByTagName fonctionnent toujours ; les deux dernières renvoient des collections dynamiques (live) qui se mettent à jour automatiquement.

Lire et écrire du contenu

Une fois que vous avez un élément, vous pouvez lire ou remplacer son contenu.

// content.js
const heading = document.querySelector("#title");

heading.textContent;          // read the visible text
heading.textContent = "Hello"; // replace it, escaped as text

heading.innerHTML = "<em>Hi</em>"; // parses HTML

Utilisez textContent dès que la valeur provient d’un utilisateur, d’une API ou de toute source que vous ne contrôlez pas entièrement. Cela traite tout comme du texte brut et ne peut pas injecter de balisage. innerHTML analyse une chaîne de caractères comme du HTML, ce qui est pratique pour des templates de confiance, mais représente un risque sérieux de cross-site scripting avec des entrées non fiables. Si vous devez construire du balisage à partir de données, préférez la création d’éléments et la définition de textContent pour chacun d’eux.

Attributs, classes et styles

Les attributs sont liés à l’élément et peuvent être lus ou modifiés directement.

// attrs.js
const link = document.querySelector("a");

link.getAttribute("href");
link.setAttribute("href", "/docs");
link.dataset.userId = "42"; // data-user-id="42"

link.classList.add("active");
link.classList.toggle("open");
link.classList.remove("hidden");

link.style.color = "tomato";

classList est la méthode la plus propre pour gérer les classes — cela évite la concaténation de chaînes de caractères et les doublons de classes accidentels. La propriété style permet de définir des styles inline propriété par propriété ; pour tout ce qui est thématique, privilégiez le basculement d’une classe et laissez CSS décider.

Création, insertion et suppression de nœuds

Vous créez de nouveaux nœuds avec document.createElement et vous les placez à l’aide des méthodes d’insertion.

// build.js
const item = document.createElement("li");
item.textContent = "New task";
item.classList.add("task");

const list = document.querySelector("#todos");
list.append(item);       // add at the end
list.prepend(item);      // add at the start
item.remove();           // detach from the tree

append accepte plusieurs nœuds et même des chaînes de caractères, tandis que insertBefore permet un placement précis. Lorsque vous devez insérer de nombreux nœuds, construisez-les hors du document et attachez-les en une seule fois :

// fragment.js
const fragment = document.createDocumentFragment();
for (const name of names) {
  const li = document.createElement("li");
  li.textContent = name;
  fragment.append(li);
}
list.append(fragment);

Un DocumentFragment est un conteneur léger qui ne fait pas partie de la page. L’attacher déplace tous ses enfants en une seule opération, ce qui déclenche beaucoup moins de calculs de mise en page (layout) que de les ajouter un par un.

Écouter les événements

Les événements permettent à votre code de répondre aux actions de l’utilisateur et du navigateur. Attachez un écouteur avec addEventListener.

// events.js
const button = document.querySelector("#save");

button.addEventListener("click", (event) => {
  event.preventDefault();
  console.log("clicked", event.target);
});

L’objet d’événement contient des informations utiles : target est l’élément qui a déclenché l’événement, currentTarget est l’élément auquel l’écouteur est attaché, et preventDefault() annule le comportement par défaut du navigateur. Les événements courants incluent click, input, change, submit, keydown, scroll et DOMContentLoaded.

Délégation d’événements

Au lieu d’attacher un écouteur à chaque enfant, attachez-en un seul au parent et inspectez event.target. Comme les événements remontent (bubble) de la cible vers ses ancêtres, le parent les voit tous.

// delegate.js
const list = document.querySelector("#todos");

list.addEventListener("click", (event) => {
  const button = event.target.closest("button.delete");
  if (!button) return;
  button.closest("li").remove();
});

C’est plus efficace et, surtout, cela continue de fonctionner pour les éléments ajoutés après l’installation de l’écouteur. Pour les listes et les tableaux dynamiques, la délégation est le pattern par défaut.

Parcourir l’arbre

Il arrive que vous ayez besoin de passer d’un nœud à ses parents ou enfants.

// traverse.js
const item = document.querySelector(".item");

item.parentElement;        // nearest ancestor element
item.children;             // child elements only
item.firstElementChild;    // first child element
item.nextElementSibling;   // next sibling element
item.closest(".card");     // nearest ancestor matching a selector

Les variantes Element ignorent les nœuds de texte et de commentaire, ce qui est presque toujours le comportement souhaité. closest est particulièrement utile dans les gestionnaires d’événements, comme le montre l’exemple sur la délégation.

Performance et bonnes pratiques

  • Regroupez vos lectures et écritures. La lecture de propriétés de mise en page comme offsetHeight force le navigateur à recalculer ; alterner lectures et écritures provoque des reflows répétés.
  • Construisez hors document. Utilisez un DocumentFragment ou un élément hors écran, puis attachez-le une seule fois.
  • Mettez vos recherches en cache. Stockez les éléments dans des variables au lieu de lancer des requêtes dans une boucle.
  • Privilégiez les classes aux styles en ligne. Basculez une classe et gardez la présentation dans le CSS.
  • Utilisez textContent par défaut. N’utilisez innerHTML qu’avec du contenu fiable et assaini.
  • Déléguez les événements pour les listes et tout élément dynamique.
  • Supprimez les écouteurs dont vous n’avez plus besoin, surtout sur les pages à longue durée de vie, pour éviter les fuites de mémoire.

Erreurs courantes

  • Interroger un élément avant qu’il n’existe, puis se demander pourquoi il est null.
  • Utiliser innerHTML avec des entrées utilisateur et créer une faille XSS.
  • Attacher un écouteur à chaque ligne au lieu de déléguer l’événement au tableau.
  • Lire et modifier des propriétés de mise en page (layout) dans une même boucle.
  • Confondre event.target et event.currentTarget.
  • Supposer que querySelectorAll est dynamique alors qu’il s’agit d’un instantané statique.

Et après ?

Le DOM est le point de convergence de tout ce que vous avez appris. Combinez-le avec la syntaxe ES6+ pour un code plus propre, alimentez-le en données via l’ Fetch API et assurez sa robustesse grâce à la gestion des erreurs. Le moyen le plus rapide de assimiler tout cela est de reconstruire un petit projet — une liste de tâches, une galerie filtrable ou une recherche en temps réel — entièrement en JavaScript vanilla.

Définir du texte en toute sécurité

textContent traite l'entrée comme du texte. innerHTML l'analyse comme du balisage, ce qui présente un risque XSS avec des données non fiables.

Préférer
const comment = "<b>hi</b>";
el.textContent = comment;
// renders the literal text
Éviter
const comment = "<img src=x onerror=alert(1)>";
el.innerHTML = comment;
// executes markup

Écouter les clics

Déléguez à un parent pour que les éléments ajoutés plus tard fonctionnent toujours et pour n'attacher qu'un seul écouteur au lieu de plusieurs.

Préférer
list.addEventListener("click", (e) => {
  const li = e.target.closest("li");
  if (li) li.remove();
});
Éviter
document.querySelectorAll("li")
  .forEach((li) => {
    li.addEventListener("click", () => li.remove());
  });

FAQ

Foire aux questions

Keep learning

Related topics from the roadmap.

$ commencer à apprendre

Prêt à apprendre DOM Manipulation ?

Notre tutoriel interactif vous guide à travers DOM Manipulation pas à pas — avec des quiz et du vrai code que vous pouvez exécuter dans le navigateur.