> Le guide complet pour manipuler le DOM en JavaScript : sélectionner, modifier le texte, le HTML, les attributs, les classes et styles, créer et supprimer des éléments, gérer les événements et la délégation.

*Source : https://coder-studio.com/tutoriels/manipuler-dom-javascript/*

---

[// Web](https://coder-studio.com/tutoriels/)

# Manipuler le DOM en JavaScript : le guide pratique

Par **Kévin Papot** · publié le 18 décembre 2025

**Manipuler le DOM**, c’est ce qui transforme une page HTML statique en interface vivante. Le DOM (Document Object Model) est la représentation en objets de votre page, que JavaScript peut lire et modifier à la volée : changer un texte, ajouter un élément, réagir à un clic. Ce guide couvre chaque opération, de la sélection d’un élément à la délégation d’événements, avec un exemple concret pour chaque cas. C’est le cœur du développement web côté navigateur.

## Sélectionner des éléments

Tout commence par récupérer une référence vers l’élément à manipuler. Les deux méthodes modernes sont `querySelector` et `querySelectorAll`, qui acceptent n’importe quel sélecteur CSS.

```
// Le premier élément qui correspond au sélecteur CSS
const titre = document.querySelector("h1");
const bouton = document.querySelector(".btn-primary");
const champ = document.querySelector("#email");
const premierItem = document.querySelector("ul li:first-child");

// Tous les éléments correspondants → NodeList
const items = document.querySelectorAll(".item");

// Méthodes historiques, toujours valides
const parId = document.getElementById("email");
const parClasse = document.getElementsByClassName("item"); // HTMLCollection live
const parBalise = document.getElementsByTagName("p");
```

`querySelectorAll` renvoie une `NodeList` que l’on parcourt facilement avec `forEach`.

```
document.querySelectorAll(".item").forEach((item) => {
  console.log(item.textContent);
});
```

On peut aussi restreindre une recherche à l’intérieur d’un élément, plutôt que sur tout le document.

```
const carte = document.querySelector(".carte");
const titreCarte = carte.querySelector("h2"); // cherche seulement dans .carte
```

## Modifier le texte

Pour lire ou écrire du texte, `textContent` est le choix par défaut : il traite le contenu comme du texte brut, sans interpréter le HTML.

```
const titre = document.querySelector("h1");

titre.textContent = "Nouveau titre";        // écrit
const actuel = titre.textContent;            // lit

// textContent échappe le HTML — sûr contre l'injection
titre.textContent = "<b>pas gras</b>";       // affiche littéralement les balises
```

## Modifier le HTML

`innerHTML` interprète les balises. Puissant, mais à réserver au contenu que vous contrôlez : n’y injectez **jamais** de saisie utilisateur brute, sous peine de faille XSS.

```
const conteneur = document.querySelector(".conteneur");

conteneur.innerHTML = "<p>Un <strong>paragraphe</strong> riche.</p>";

// Ajouter sans tout écraser
conteneur.innerHTML += "<p>Second paragraphe.</p>";

// insertAdjacentHTML : plus précis, sans réanalyser tout le contenu
conteneur.insertAdjacentHTML("beforeend", "<p>Ajouté à la fin.</p>");
// Positions : beforebegin, afterbegin, beforeend, afterend
```

## Modifier les attributs

Les attributs HTML (href, src, disabled, data-…) se lisent et s’écrivent avec des méthodes dédiées.

```
const lien = document.querySelector("a");

lien.getAttribute("href");              // lire
lien.setAttribute("href", "/contact"); // écrire
lien.hasAttribute("target");            // tester
lien.removeAttribute("target");         // supprimer

// Propriétés directes pour les attributs courants
lien.href = "/accueil";
const img = document.querySelector("img");
img.src = "/logo.png";
img.alt = "Logo";

// Attributs data-*
const el = document.querySelector(".produit");
el.dataset.prix = "49";           // écrit data-prix="49"
console.log(el.dataset.prix);     // lit "49"
```

## Modifier les classes CSS

L’objet `classList` gère les classes proprement, sans écraser les autres.

```
const boite = document.querySelector(".boite");

boite.classList.add("active");            // ajoute
boite.classList.remove("cachee");         // retire
boite.classList.toggle("ouvert");         // bascule (ajoute/retire)
boite.classList.contains("active");       // teste → true/false
boite.classList.replace("v1", "v2");      // remplace

// toggle avec condition
boite.classList.toggle("valide", champ.value !== "");
```

## Modifier les styles

On agit directement sur la propriété `style` (styles inline) ou, mieux, on bascule des classes définies en CSS.

```
const boite = document.querySelector(".boite");

boite.style.color = "white";
boite.style.backgroundColor = "navy";     // camelCase pour background-color
boite.style.display = "none";

// Plusieurs propriétés d'un coup avec cssText
boite.style.cssText = "color: white; padding: 1rem;";

// Lire le style calculé (résultat final, y compris CSS externe)
const couleur = getComputedStyle(boite).color;

// Variables CSS
boite.style.setProperty("--accent", "#e11");
```

En pratique, préférez `classList` à `style` : garder l’apparence dans le CSS rend le code plus maintenable.

## Créer et insérer des éléments

Pour construire du contenu proprement, on crée les éléments en JavaScript puis on les insère.

```
// 1. Créer
const item = document.createElement("li");
item.textContent = "Nouvel élément";
item.classList.add("item");

// 2. Insérer dans un parent
const liste = document.querySelector("ul");
liste.append(item);        // à la fin (accepte texte + plusieurs nœuds)
liste.prepend(item);       // au début
liste.appendChild(item);   // équivalent historique, à la fin

// Insérer avant/après un élément précis
const reference = document.querySelector(".item");
reference.before(item);    // juste avant
reference.after(item);     // juste après
```

Quand on ajoute beaucoup d’éléments, un `DocumentFragment` évite de toucher la page à chaque itération, ce qui améliore les performances.

```
const fragment = document.createDocumentFragment();
["Paris", "Lyon", "Nice"].forEach((ville) => {
  const li = document.createElement("li");
  li.textContent = ville;
  fragment.append(li);
});
document.querySelector("ul").append(fragment); // une seule insertion
```

Cette boucle s’appuie sur les [méthodes de tableau](https://coder-studio.com/tutoriels/tableaux-javascript-methodes/) pour générer le contenu.

## Supprimer et remplacer des éléments

La suppression est directe avec `remove()`.

```
const el = document.querySelector(".obsolete");
el.remove(); // se retire lui-même du DOM

// Vider un conteneur
const liste = document.querySelector("ul");
liste.replaceChildren(); // supprime tous les enfants

// Remplacer un élément par un autre
const nouveau = document.createElement("p");
nouveau.textContent = "Remplaçant";
document.querySelector(".ancien").replaceWith(nouveau);

// Cloner un élément
const copie = el.cloneNode(true); // true = avec les enfants
```

## Naviguer dans l’arbre du DOM

Depuis un élément, on peut atteindre ses voisins, parents et enfants.

```
const el = document.querySelector(".item");

el.parentElement;            // parent direct
el.children;                 // enfants (éléments seulement)
el.firstElementChild;        // premier enfant
el.lastElementChild;         // dernier enfant
el.nextElementSibling;       // frère suivant
el.previousElementSibling;   // frère précédent
el.closest(".conteneur");    // ancêtre le plus proche correspondant
```

## Gérer les événements

`addEventListener` attache une fonction qui s’exécute quand un événement se produit (clic, saisie, envoi de formulaire…).

```
const bouton = document.querySelector(".btn");

bouton.addEventListener("click", (event) => {
  console.log("Bouton cliqué !");
  console.log(event.target); // l'élément déclencheur
});

// Événements courants
const champ = document.querySelector("input");
champ.addEventListener("input", (e) => console.log(e.target.value));
champ.addEventListener("focus", () => console.log("champ actif"));

const formulaire = document.querySelector("form");
formulaire.addEventListener("submit", (e) => {
  e.preventDefault(); // empêche le rechargement de la page
  console.log("Formulaire soumis");
});
```

On retire un écouteur avec `removeEventListener`, à condition d’avoir une référence à la fonction (pas une fonction anonyme).

```
function gerer() {
  console.log("clic");
}
bouton.addEventListener("click", gerer);
bouton.removeEventListener("click", gerer);

// Écouteur qui ne se déclenche qu'une fois
bouton.addEventListener("click", gerer, { once: true });
```

Ces callbacks reposent sur les [fonctions fléchées](https://coder-studio.com/tutoriels/fonctions-flechees-closures-js/), attention toutefois au `this` : dans une fonction fléchée, `this` n’est pas l’élément ; utilisez `event.currentTarget` à la place.

## La délégation d’événements

Attacher un écouteur à chaque élément d’une longue liste est coûteux, et ne fonctionne pas pour les éléments ajoutés après coup. La **délégation** résout les deux problèmes : on écoute sur le parent et on identifie la cible grâce à la propagation des événements (event bubbling).

```
const liste = document.querySelector("ul");

// Un seul écouteur pour tous les <li>, présents et futurs
liste.addEventListener("click", (event) => {
  const item = event.target.closest("li");
  if (!item) return; // clic hors d'un li

  console.log("Clic sur :", item.textContent);
  item.classList.toggle("selectionne");
});
```

Ce patron est essentiel dans les interfaces dynamiques : un seul écouteur gère un nombre illimité d’éléments, y compris ceux insérés plus tard.

## À retenir

Manipuler le DOM suit toujours le même cycle : **sélectionner** un élément (`querySelector`), le **modifier** (texte, HTML, attributs, classes, styles), ou **créer/insérer/supprimer** des nœuds, puis **réagir** aux actions de l’utilisateur avec `addEventListener`. Deux réflexes de qualité : préférez `textContent` et `classList` à `innerHTML` et `style` quand c’est possible, et utilisez la délégation d’événements dès que vous manipulez des listes dynamiques. Avec ces bases, vous pouvez construire n’importe quelle interaction côté navigateur.

## À lire ensuite

-   [Les tableaux en JavaScript : map, filter, reduce et toutes les méthodes](https://coder-studio.com/tutoriels/tableaux-javascript-methodes/)
-   [async/await et les promesses en JavaScript](https://coder-studio.com/tutoriels/async-await-promesses-js/)
-   [Apprendre JavaScript : par où commencer](https://coder-studio.com/tutoriels/apprendre-javascript/)
