Detecta cambios del DOM con observadores de mutación

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

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

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

Los observadores de mutaciones del DOM, que se introdujeron en la especificación DOM4, reemplazarán a los eventos de mutación. Mientras que los eventos de mutación activaban eventos lentos para cada cambio, los observadores de mutaciones son más rápidos con 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 produjeron en el DOM.

Puedes comenzar a usar los observadores de mutaciones en Chrome Beta para detectar cambios en el DOM y tenerlos listos para usarlos cuando se lance la versión estable (Chrome 18). Si actualmente usas los eventos de mutación obsoletos, migra a Mutation Observers.

Este es 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í se ve con los observadores de mutaciones:

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