Detecteer DOM-veranderingen met mutatiewaarnemers

In 2000 werd de Mutation Events API gespecificeerd om het voor ontwikkelaars gemakkelijk te maken om te reageren op veranderingen in een DOM (bijv. DOMNodeRemoved, DOMAttrModified, enz.).

Deze functie werd niet veel gebruikt door webontwikkelaars, maar het bood een erg handig en populair gebruiksscenario voor Chrome-extensies als ze een actie wilden uitvoeren wanneer er iets op de pagina veranderde.

Mutatiegebeurtenissen zijn nuttig, maar veroorzaken tegelijkertijd enkele prestatieproblemen. De gebeurtenissen zijn traag en worden te vaak op een synchrone manier geactiveerd, wat enkele ongewenste browserbugs veroorzaakt.

Geïntroduceerd in de DOM4-specificatie , zullen DOM Mutation Observers Mutation Events vervangen. Terwijl Mutation Events langzame gebeurtenissen afvuurde voor elke afzonderlijke wijziging, zijn Mutation Observers sneller met behulp van callback-functies die kunnen worden geleverd na meerdere wijzigingen in de DOM.

U kunt de lijst met wijzigingen die de API biedt handmatig afhandelen , of een bibliotheek zoals Mutation Summary gebruiken, die deze taak eenvoudiger maakt en een laag betrouwbaarheid toevoegt aan de wijzigingen die in de DOM hebben plaatsgevonden.

U kunt Mutation Observers in Chrome Bèta gaan gebruiken om veranderingen in de DOM te detecteren en klaar te zijn om deze te gebruiken als het om stabiel gaat (Chrome 18). Als u momenteel de verouderde Mutation Events gebruikt, migreert u gewoon naar Mutation Observers.

Hier is een voorbeeld van het weergeven van ingevoegde knooppunten met mutatiegebeurtenissen:

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

En zo ziet het eruit met Mutation Observers:

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);