Vous avez sûrement déjà vécu cette situation : une partie de votre page change mais votre JavaScript ne le remarque pas. Un élément est ajouté, supprimé ou modifié dans le DOM, et pourtant votre script ne détecte rien. Il existe une solution propre, moderne et très puissante pour surveiller en temps réel les changements du DOM : MutationObserver.
- Repérer automatiquement une modification du DOM sans bricolage ni boucle inefficace
- Rendre vos interfaces dynamiques plus intelligentes en réagissant en temps réel aux changements du DOM
- Gagner en performance et en propreté de code en maîtrisant une méthode moderne et fiable adaptée aux projets réels
Dans ce tutoriel, vous allez découvrir comment détecter une modification DOM en JavaScript, comprendre les concepts derrière, et surtout les utiliser concrètement dans vos projets.
- Comprendre le DOM
- Pourquoi détecter un changement du DOM ?
- La vraie solution : MutationObserver
- Comprendre les types de modification DOM
- Exemple concret : détecter un changement de classe
- Observer tout un sous-arbre du DOM
- Exemple pratique : détecter un élément injecté dynamiquement
- Comment arrêter l’observation
- Aller plus loin : exploiter pleinement les changements du DOM
- Cas concret : ajouter automatiquement un événement
- Cas avancé : surveiller un attribut précis
- Les erreurs fréquentes et comment les éviter
Comprendre le DOM
Avant de parler de changement DOM, il faut bien comprendre ce qu’est le DOM.
Le DOM (Document Object Model) est une représentation de votre page HTML sous forme d’arbre. Chaque balise devient un “nœud” :
<div id="app">
<p>Bonjour</p>
</div>
Votre JavaScript peut lire, modifier, ajouter ou supprimer ces éléments. Et c’est là que tout devient intéressant.
👉 Pour ceux qui débutent : Comprendre le DOM en JS
Pourquoi détecter un changement du DOM ?
Imaginez plusieurs cas concrets :
- Vous utilisez un script externe qui modifie votre page
- Vous avez une interface dynamique (AJAX, React, Vue…)
- Vous voulez déclencher une action dès qu’un élément apparaît
Exemple typique :
“Dès qu’un bouton est ajouté dans la page, je veux lui ajouter un événement click.”
Sans détection de modification DOM, vous devriez vérifier en boucle… ce qui est une très mauvaise idée (et votre CPU va pleurer). Heureusement, il existe une méthode bien plus élégante.
L’ancienne méthode (à éviter) : setInterval
Avant, certains développeurs faisaient ça :
setInterval(() => {
const element = document.querySelector('.nouveau');
if (element) {
console.log('Element détecté !');
}
}, 1000);
Ça fonctionne… mais :
- c’est lent
- ça consomme des ressources inutilement
- ce n’est pas précis
Bref, c’est un peu comme vérifier toutes les minutes si quelqu’un a sonné à votre porte, au lieu d’avoir une sonnette.
La vraie solution : MutationObserver
Bienvenue dans le cœur du sujet.
MutationObserver est une API JavaScript qui permet de détecter automatiquement les changements du DOM.
- C’est propre, performant, et surtout fait pour ça.
Premier exemple simple de MutationObserver
On va commencer très doucement :
<div id="container"></div>
<button id="add">Ajouter un élément</button>
Puis, en JavaScript :
const container = document.getElementById('container');
const observer = new MutationObserver((mutations) => {
console.log('Changement détecté dans le DOM !');
console.log(mutations);
});
observer.observe(container, {
childList: true
});
Maintenant, on va ajouter un élément :
document.getElementById('add').addEventListener('click', () => {
const p = document.createElement('p');
p.textContent = "Nouvel élément";
container.appendChild(p);
});
Prenons le temps de bien comprendre.
MutationObserverécoute les changements- La fonction reçoit un tableau
mutations observe()démarre l’écoute
Et ici :
childList: true
signifie :
“Je veux détecter les ajouts ou suppressions d’enfants dans le DOM”
Comprendre les types de modification DOM
Quand on parle de changement DOM, il y a plusieurs types de modifications possibles.
1. Ajout ou suppression d’éléments
C’est le cas le plus courant.
childList: true
2. Modification d’attributs
Par exemple :
<div id="box" class="red"></div>
Si vous changez la classe :
box.classList.add('active');
Pour détecter ça :
observer.observe(box, {
attributes: true
});
3. Modification du contenu texte
Prenons comme exemple :
box.textContent = "Nouveau texte";
À surveiller avec :
observer.observe(box, {
characterData: true,
subtree: true
});
Exemple concret : détecter un changement de classe
Le code HTML :
<div id="box">Test</div>
<button id="change">Changer classe</button>
Puis, en JavaScript :
const box = document.getElementById('box');
const observer = new MutationObserver((mutations) => {
mutations.forEach((mutation) => {
if (mutation.type === 'attributes') {
console.log('Attribut modifié !');
console.log('Nouvelle classe :', box.className);
}
});
});
observer.observe(box, {
attributes: true
});
document.getElementById('change').addEventListener('click', () => {
box.classList.toggle('active');
});
À chaque modification DOM sur les attributs :
- MutationObserver capte le changement et vous pouvez réagir immédiatement
C’est ultra puissant.
Observer tout un sous-arbre du DOM
Très souvent, vous ne voulez pas surveiller un seul élément, mais toute une zone.
C’est là que subtree entre en jeu.
observer.observe(container, {
childList: true,
subtree: true
});
Cela signifie :
“Observe tous les changements dans cet élément ET tous ses enfants.”
Exemple pratique : détecter un élément injecté dynamiquement
Imaginez un script externe qui ajoute un bouton.
setTimeout(() => {
const btn = document.createElement('button');
btn.textContent = "Cliquez-moi";
document.body.appendChild(btn);
}, 2000);
Vous voulez détecter ce bouton automatiquement.
const observer = new MutationObserver((mutations) => {
mutations.forEach((mutation) => {
mutation.addedNodes.forEach((node) => {
if (node.tagName === 'BUTTON') {
console.log('Bouton ajouté !');
}
});
});
});
observer.observe(document.body, {
childList: true,
subtree: true
});
Pourquoi c’est formidable ?
Parce que :
- vous n’avez pas besoin de savoir quand l’élément arrive
- votre code reste réactif
- c’est parfaitement adapté aux interfaces modernes
Comment arrêter l’observation
Un observer actif en permanence peut être inutile. Mais vous avez aussi la possibilité de le stopper.
Pour l’arrêter :
observer.disconnect();
Très utile si :
- vous avez déjà détecté ce que vous vouliez
- vous changez de page (SPA)
- vous voulez optimiser les performances
Erreur fréquente de débutant
Attention à ceci :
- MutationObserver peut déclencher plusieurs mutations pour une seule action.
Donc évitez de faire :
Des formations informatique pour tous !
Débutant ou curieux ? Apprenez le développement web, le référencement, le webmarketing, la bureautique, à maîtriser vos appareils Apple et bien plus encore…
Formateur indépendant, professionnel du web depuis 2006, je vous accompagne pas à pas et en cours particulier, que vous soyez débutant ou que vous souhaitiez progresser. En visio, à votre rythme, et toujours avec pédagogie.
Découvrez mes formations Qui suis-je ?console.log('changement');
sans filtrer.
Préférez analyser :
mutation.type
mutation.addedNodes
mutation.attributeName
Sinon, vous allez vite vous retrouver avec des logs dans tous les sens.
Cas concret
Sur un site web, vous pourriez avoir besoin de :
- détecter automatiquement des nouveaux éléménts
- recalculer un résultat dès modification DOM
- analyser les nouveautés en temps réel
Exemple :
if (node.tagName === 'A') {
console.log('Nouveau lien détecté :', node.href);
}
Aller plus loin : exploiter pleinement les changements du DOM
Vous avez maintenant compris comment détecter un changement DOM avec MutationObserver. Mais soyons honnêtes : dans un vrai projet, ce n’est jamais aussi simple.
Les pages deviennent complexes, les modifications DOM sont nombreuses, et si vous ne structurez pas bien votre logique… c’est vite le chaos.
Filtrer intelligemment les mutations
Quand un changement du DOM se produit, vous recevez souvent beaucoup d’informations. Trop, parfois.
- Si vous traitez tout sans réfléchir, votre script risque de devenir lent ou imprécis.
const observer = new MutationObserver((mutations) => {
console.log(mutations);
});
Cela affiche tout… mais ça ne sert pas à grand-chose. Une bonne pratique serait de filtrer les mutations utiles.
Prenons un cas concret :
Vous voulez détecter uniquement les nouveaux liens (
<a>)
const observer = new MutationObserver((mutations) => {
mutations.forEach((mutation) => {
if (mutation.type === 'childList') {
mutation.addedNodes.forEach((node) => {
if (node.nodeType === 1 && node.tagName === 'A') {
console.log('Lien détecté :', node.href);
}
});
}
});
});
observer.observe(document.body, {
childList: true,
subtree: true
});
Maintenant, vous avez :
- ciblé uniquement les ajouts (
childList) - ignoré le bruit inutile
- filtré les vrais éléments HTML (
nodeType === 1) - ciblé un type précis (
A)
C’est exactement comme ça qu’on travaille proprement.
Optimiser les performances
Un MutationObserver, c’est puissant… mais mal utilisé, ça peut ralentir votre site. Un peu comme un stagiaire hyper motivé qui regarde absolument tout, tout le temps.
Commencer par limiter la zone observée, il faut donc évitez ceci :
observer.observe(document.body, {
subtree: true
});
Mieux vaut :
observer.observe(document.getElementById('app'), {
subtree: true
});
Ainsi vous réduisez le nombre de modifications DOM à analyser.
Veillez à ne surveiller que ce qui est nécessaire. Inutile de tout activer :
attributes: true,
childList: true,
characterData: true
Si vous avez juste besoin des ajouts :
childList: true
Simple, efficace.
Débouncer les actions
Si beaucoup de changements DOM arrivent en même temps, votre fonction peut être appelée en boucle. La meilleure solution : temporiser.
let timeout;
const observer = new MutationObserver(() => {
clearTimeout(timeout);
timeout = setTimeout(() => {
console.log('Traitement après stabilisation du DOM');
}, 200);
});
Cela permet d’attendre que le DOM “se calme” avant d’agir. C’est comme attendre que tout le monde ait fini de parler avant de répondre.
Cas concret : ajouter automatiquement un événement
Imaginez :
Vous voulez que chaque bouton ajouté dynamiquement ait un événement click.
const observer = new MutationObserver((mutations) => {
mutations.forEach((mutation) => {
mutation.addedNodes.forEach((node) => {
if (node.nodeType === 1 && node.tagName === 'BUTTON') {
node.addEventListener('click', () => {
alert('Bouton cliqué !');
});
}
});
});
});
observer.observe(document.body, {
childList: true,
subtree: true
});
Même les boutons ajoutés après coup fonctionnent immédiatement. Et ça, pour une interface dynamique, c’est de l’or.
Cas avancé : surveiller un attribut précis
Vous pouvez aller encore plus loin.
Exemple :
Vous voulez détecter uniquement les changements de classe.
observer.observe(element, {
attributes: true,
attributeFilter: ['class']
});
Pourquoi utiliser attributeFilter ?
Parce que sinon, vous écoutez TOUS les attributs :
- id
- style
- data-*
- etc.
Et encore une fois… du bruit inutile.
Les erreurs fréquentes et comment les éviter
Voici les pièges classiques.
1. Observer trop large
Résultat : performances mauvaises.
👉 Solution : cibler un conteneur précis
2. Ne pas filtrer
Résultat : logs inutiles, bugs
👉 Solution : analyser mutation.type
3. Oublier disconnect()
Résultat : fuite de performance
👉 Solution :
observer.disconnect();
4. Ne pas vérifier nodeType
Résultat : erreurs avec des nœuds texte
👉 Toujours faire :
if (node.nodeType === 1)
Une analogie simple pour tout retenir
Imaginez que le DOM est une maison.
MutationObserver= une caméra de surveillanceobserve()= vous choisissez les pièces à surveillermutations= les événements détectés
Et vous pouvez décider :
- d’ignorer certains mouvements
- de déclencher une alarme
- ou de ne rien faire
Vous venez de découvrir un outil extrêmement puissant : la détection de changement du DOM en JavaScript.
Et ce n’est pas juste un “truc technique”. C’est un véritable atout pour rendre vos interfaces intelligentes, réactives et modernes.
Ce qu’il faut vraiment retenir, ce n’est pas seulement comment utiliser MutationObserver, mais pourquoi vous l’utilisez. Derrière chaque modification DOM, il y a une opportunité : automatiser, analyser, améliorer.

Fondateur de l’agence Créa-troyes, affiliée France Num
Intervenant en Freelance.
Contactez-moi
