Manipulation du DOM
Introduction
Une fois capable de détecter une action de l'utilisateur (cours
précédent), il reste à modifier la page en réponse. C'est ce que permet le
DOM — Document Object Model — la représentation du document HTML sous
forme d'un arbre d'objets manipulables depuis JavaScript. Chaque balise du
HTML devient un objet JS avec des propriétés (textContent, style, id…)
et des méthodes (appendChild, setAttribute…).
Voir .
Qu'est-ce que le DOM ?
Quand un navigateur charge une page HTML, il construit en mémoire un arbre qui reflète la structure imbriquée des balises. Le HTML suivant :
<body>
<h1 id="titre">Bonjour</h1>
<p class="intro">Bienvenue.</p>
</body>
donne, en mémoire, un arbre dont la racine est document :
document
└── <html>
├── <head>...</head>
└── <body>
├── <h1 id="titre">Bonjour</h1>
└── <p class="intro">Bienvenue.</p>
JavaScript dispose d'un objet global document qui sert de point d'entrée
à cet arbre. Tout ce qui suit en découle.
Sélectionner des éléments
Cinq méthodes principales sur document :
// Par identifiant (un seul élément, ou null)
const titre = document.getElementById("titre");
// Par classe (collection vivante d'éléments)
const intros = document.getElementsByClassName("intro");
// Par nom de balise (collection vivante)
const tousLesP = document.getElementsByTagName("p");
// Par sélecteur CSS — premier élément trouvé
const premier = document.querySelector(".intro");
// Par sélecteur CSS — tous les éléments
const tous = document.querySelectorAll("p.intro");
| Méthode | Renvoie | Quand l'utiliser |
|---|---|---|
getElementById("x") | L'élément avec cet id, ou null. | Cible unique connue par id. |
getElementsByClassName("c") | Collection HTML d'éléments. | Plusieurs éléments par classe. |
getElementsByTagName("t") | Collection HTML d'éléments. | Tous les éléments d'un type. |
querySelector("…") | Le premier élément correspondant, ou null. | Cible unique via sélecteur CSS. |
querySelectorAll("…") | Liste statique d'éléments. | Plusieurs éléments via sélecteur CSS. |
querySelector et querySelectorAll suffisent à presque
tout : ils acceptent n'importe quel sélecteur CSS (#id, .classe,
tag.classe, ul > li.actif…). Privilégiez-les pour la cohérence.Que renvoie document.getElementById('inconnu') si aucun élément n'a cet id ?
Modifier le contenu d'un élément
Une fois un élément sélectionné, on peut lire ou modifier son contenu :
const titre = document.getElementById("titre");
// Lire le texte
console.log(titre.textContent); // "Bonjour"
// Remplacer le texte
titre.textContent = "Bonsoir";
// Injecter du HTML (avec balises interprétées)
titre.innerHTML = "Salut <em>tout le monde</em>";
Différence cruciale :
.textContenttraite la valeur comme du texte brut. Sûr et rapide..innerHTMLinterprète la valeur comme du HTML. Puissant mais dangereux si la valeur vient d'un utilisateur (risque d'injection).
element.innerHTML = saisieUtilisateur sans précaution :
c'est la principale source de failles XSS (cross-site scripting).
Préférer element.textContent = saisieUtilisateur.Modifier des attributs
Trois opérations standard :
const img = document.getElementById("photo");
// Lire un attribut
console.log(img.getAttribute("src"));
// Définir / changer un attribut
img.setAttribute("alt", "Nouvelle description");
// Supprimer un attribut
img.removeAttribute("title");
Pour certains attributs courants, on peut aussi y accéder en tant que propriété :
img.src = "nouveau.jpg";
img.alt = "Description";
const lien = document.querySelector("a");
lien.href = "https://nsi.rocks";
Modifier le style
Deux approches, à choisir selon le contexte :
const titre = document.getElementById("titre");
// 1. Propriété par propriété (style inline)
titre.style.color = "navy";
titre.style.fontSize = "32px"; // notez le camelCase
titre.style.backgroundColor = "yellow";
// 2. Ajouter / retirer une classe CSS (préféré)
titre.classList.add("souligne");
titre.classList.remove("ancien");
titre.classList.toggle("actif"); // bascule on/off
.style : elle laisse le CSS gérer la présentation et le JS
gérer le comportement (« telle classe est active »). Plus propre, plus
maintenable./* dans le CSS */
.souligne { text-decoration: underline; }
.actif { background-color: yellow; }
Quelle méthode bascule une classe CSS on/off ?
Créer et insérer un élément
Pour ajouter un nouvel élément à la page :
// 1. Créer
const nouveau = document.createElement("p");
// 2. Le remplir
nouveau.textContent = "Paragraphe ajouté par JS.";
nouveau.classList.add("ajout");
// 3. L'insérer dans un parent existant
const conteneur = document.getElementById("conteneur");
conteneur.appendChild(nouveau);
Pour supprimer un élément :
nouveau.remove();
(Avant 2019 il fallait parent.removeChild(enfant) ; aujourd'hui .remove()
sur l'élément lui-même suffit.)
Un exemple complet — compteur cliquable
Mettons bout à bout ce que vous avez vu : sélection, écouteur, modification.
<button id="bouton">J'ai été cliqué 0 fois</button>
const bouton = document.getElementById("bouton");
let compteur = 0;
bouton.addEventListener("click", function() {
compteur += 1;
bouton.textContent = `J'ai été cliqué ${compteur} fois`;
});
Au clic, le compteur s'incrémente et le texte du bouton est réécrit par JS dans le DOM. Aucune requête réseau, aucun rechargement. C'est le cœur de l'interactivité Web moderne.
Un exemple plus riche — formulaire dynamique
<form id="form">
<input type="text" id="nom" placeholder="Votre prénom" required>
<button type="submit">Saluer</button>
</form>
<p id="message"></p>
const form = document.getElementById("form");
const message = document.getElementById("message");
form.addEventListener("submit", function(event) {
event.preventDefault(); // bloquer la soumission classique
const nom = document.getElementById("nom").value;
message.textContent = `Bonjour, ${nom} !`;
message.style.color = "navy";
});
Ici, event.preventDefault() empêche le navigateur de soumettre le
formulaire (et donc de recharger la page), ce qui permet de gérer la saisie
entièrement en JavaScript.
Quelle propriété d'un input texte permet de lire la valeur saisie en JavaScript ?
Cas particuliers et pièges
nullnon géré :document.getElementById("xyz")peut renvoyernullsi l'id n'existe pas. Tenter d'accéder à.textContentsurnullprovoque une erreur. Toujours vérifier ou utiliser?.(optional chaining).- Le script s'exécute trop tôt : si le script s'exécute avant que le HTML
soit chargé, les éléments n'existent pas encore dans le DOM. Utiliser
defersur le<script>ou écouterDOMContentLoaded. getElementsByClassNameest vivant : la collection se met à jour toute seule quand le DOM change — surprise garantie dans une boucle qui ajoute des éléments.style.background-colorne marche pas : en JavaScript, les propriétés CSS sont encamelCase:style.backgroundColor,style.fontSize…
Pour aller plus loin
Le pattern événement + modification du DOM est le moteur de toute page interactive. Les frameworks modernes (Vue, React, Svelte) automatisent ces opérations, mais reposent tous, en dessous, sur les mêmes API du DOM. Le cours suivant ouvre l'horizon : comment cette page parle-t-elle au serveur via HTTP ?