Detecta cambios del DOM con observadores de mutación

En el año 2000, se especificó la API de eventos de mutación para que los desarrolladores pudieran reaccionar fácilmente ante los cambios en un DOM (p.ej., DOMNodeRemoved, DOMAttrModified, etcétera).

Esta función no era muy utilizada por los desarrolladores web, pero presentaba un caso de uso muy conveniente y popular para las extensiones de Chrome si querían realizar alguna acción cuando algo en la página cambiaba.

Los eventos de mutación son útiles, pero, al mismo tiempo, generan algunos problemas de rendimiento. Los eventos son lentos y se activan con demasiada frecuencia de forma síncrona, lo que genera algunos errores no deseados en el navegador.

Introducidos en la especificación de DOM4, los observadores de mutación del DOM reemplazarán a los eventos de mutación. Mientras que los eventos de mutación activaron eventos lentos para cada cambio, los observadores de mutación son más rápidos con las funciones de devolución de llamada que se pueden entregar después de varios cambios en el DOM.

Puedes controlar de forma manual la lista de cambios que ofrece la API o usar una biblioteca como Mutation Summary, que facilita esta tarea y agrega una capa de confiabilidad sobre los cambios que se realizaron en el DOM.

Puedes comenzar a usar Mutation Observers en Chrome Beta para detectar cambios en el DOM y estar listo para usarlo cuando se trate de una versión estable (Chrome 18). Si actualmente estás usando los eventos de mutación obsoletos, simplemente migra a Mutation Observers.

A continuación, te mostramos un ejemplo de cómo enumerar los nodos insertados con eventos de mutación:

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

Y así es como se ve con 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);