Détecter les modifications DOM avec des observateurs de mutation

En 2000, l'API Mutation Events a été spécifiée pour permettre aux développeurs de réagir facilement aux modifications apportées à un DOM (par exemple, DOMNodeRemoved, DOMAttrModified, etc.).

Cette fonctionnalité n'était pas très utilisée par les développeurs Web, mais elle représentait un cas d'utilisation très pratique et populaire des extensions Chrome s'ils souhaitaient effectuer une action lorsqu'un élément de la page changeait.

Les événements de mutation sont utiles, mais ils peuvent entraîner des problèmes de performances. Les événements sont lents et sont déclenchés trop fréquemment de manière synchrone, ce qui provoque des bugs de navigateur indésirables.

Introduits dans la spécification DOM4, les observateurs de mutation DOM vont remplacer les événements de mutation. Contrairement aux événements de mutation qui déclenchaient des événements lents pour chaque modification, les observateurs de mutations sont plus rapides grâce à des fonctions de rappel qui peuvent être fournies après plusieurs modifications dans le DOM.

Vous pouvez gérer manuellement la liste des modifications proposées par l'API ou utiliser une bibliothèque telle que Mutation Summary (Résumé de la mutation) qui facilite cette tâche et ajoute une couche de fiabilité aux modifications apportées dans le DOM.

Vous pouvez commencer à utiliser les observateurs de mutation dans la version bêta de Chrome pour détecter les modifications dans le DOM et être prêt à l'utiliser lorsqu'il sera stable (Chrome 18). Si vous utilisez actuellement les événements de mutation obsolètes, passez simplement à "Observateurs de mutation".

Voici un exemple de liste de nœuds insérés avec des événements de mutation:

var insertedNodes = [];
document.addEventListener("DOMNodeInserted", function(e) {
    insertedNodes.push(e.target);
}, false);
console.log(insertedNodes);

Voici à quoi cela ressemble avec le programme d'observation de mutations:

var insertedNodes = [];
var observer = new MutationObserver(function(mutations) {
    mutations.forEach(function(mutation) {
    for (var i = 0; i < mutation.addedNodes.length; i++)
        insertedNodes.push(mutation.addedNodes[i]);
    })
});
observer.observe(document.documentElement, { childList: true });
console.log(insertedNodes);