MutationObserver te da la capacidad de observar los cambios que puede sufrir un elemento del DOM (HTML). Esos cambios incluyen el contenido del elemento, cambios en sus atributos, incluso si ha sido eliminado, entre otros.

const element = document.getElementById("element");

let observer = new MutationObserver(function(mutations) {

  for(const mutation of mutations) {
    console.log(mutation.type);
  }
  
  observer.disconnect();
})

observer.observe(element, {
  attributes: true, 
  childList: true, 
  characterData: true
});

Por ejemplo, detectar cuando se quita o agrega una clase. En este caso en un elemento <strong>.

Ejemplo en vivo
MutationObserver

Sintaxis

let observer = new MutationObserver(callback);

function callback(mutations) { 
	for(mutation of mutations) {
		console.log(mutation.type);
    }
    
    observer.disconnect();
}

observer.observe(element, options);

Opciones

Para especificar las opciones se necesita de un objeto conocido como MutationObserverInit el cual cuenta con una serie de propiedades que deben ser especificadas como true o false (a excepción de attributeFilter) dependiendo lo que se necesite.

observer.observe(element, {
	childList: true,
	attributes: true,
	characterData: true,
	subtree: true,
	attributeOldValue: true,
	characterDataOldValue: true,
	attributeFilter: ["class", "id", "style"]
});
Opción Descripción
childList Especifica si los cambios en un nodo o varios, deben ser observados.
attributes Especifica si los cambios en los atributos deben ser observados.
characterData Especifica si los cambios en el contenido textual de un nodo o varios, deben ser observados.
subtree Especifica si los cambios en los descendientes deben ser observados.
attributeOldValue Especifica si el valor anterior del atributo al cambio debe ser guardado.
characterDataOldValue Especifica si el dato anterior al cambio debe ser guardado.
attributeFilter Especifica un array los nombres de atributos cuyos valores se deben monitorear para detectar cambios.

Para que el MutationObserver funcione debes de tener al menos childList, attributes o characterData como true.

Métodos

Al tener nuestra instancia (observe) declarada, de forma automática tenemos acceso a tres diferentes métodos, esos métodos son:

observe()

El método observe() registra la instancia de MutationObserver para recibir notificaciones de los cambios en el DOM en el elemento.

observer.observe(element, options);

disconnect()

Desconecta la instancia de MutationObserver para ya no recibir notificaciones de los cambios en el DOM.

observer.disconnect();

takeRecords()

El método takeRecords() devuelve un array de todos los cambios del DOM que han coincidido, pero que no han pasado por la función callback(), esto hace que la cola de la mutación quede vacía.

let registros = observador.takeRecords();

Si quieres aprender acerca de este método, puedes ver la documentación de MDN y saber más al respecto.

Objecto MutationRecord

El callback recibe un argumento, este argumento es el objeto MutationRecord, el cual contiene información acerca del elemento que es observado.

    
 let observer = new MutationObserver(callback);

 function callback(mutations) { // MutationRecord 
	 for(mutation of mutations) {
		 console.log(mutation.type); // Propiedades
     }
    
     observer.disconnect();
 }

 observer.observe(element, options);
    

Las propiedades a las que podemos acceder son las siguientes:

Propiedad Descripción
type Devuelve un String con tipo de mutación que sufrió el elemento.

  • attributes si el cambio fue en un atributo.
  • characterData si el cambio se produjo en un nodo.
  • childList si el cambio se produjo en los textos de los nodos del árbol.
target Dependiendo el type devuelve un Node con el nodo afectado por la mutación.

  • Para attributes, el elemento cuyos atributos han cambiado.
  • Para characterData, el nodo CharacterData.
  • Para childList, El nodo padre cuyos hijos se han visto afectados.
addedNodes Devuelve un NodeList de los nodos que se han agregado. Si no hay nodos, devuelve un NodeList vacío.
removedNodes Devuelve un NodeList de los nodos que se han eliminado. Si no hay nodos, devuelve un NodeList vacío.
previousSibling Devuelve el nodo hermano anterior (ya sea que se añadió o elimino), también puede regresar null.
nextSibling Devuelve el siguiente nodo hermano (ya sea que se añadió o elimino), también puede regresar null.
attributeName Devuelve el nombre local del atributo alterado, también puede regresar null.
attributeNamespace Devuelve espacio de nombres (namespace) del atributo alterado, también puede regresar null.
oldValue Dependiendo el type devuelve un String con un valor.

  • Para attributes, el valor anterior del atributo.
  • Para characterData, los datos antes del cambio
  • Para childList, devuelve null.

Recursos