JavaScript de Cero a Experto / APIs del navegador
MutationObserver y ResizeObserver: cámaras del DOM
La familia de observers tiene dos hermanos más: MutationObserver vigila
CAMBIOS en el árbol del DOM (algo se agregó, se quitó, cambió un
atributo), y ResizeObserver vigila el TAMAÑO de elementos concretos.
Los usarás menos que al portero de la lección pasada — pero cuando los
necesitas, no hay sustituto, y entenderlos te explica cómo funcionan por
dentro varias herramientas que ya usas.
Las cámaras de seguridad
MutationObserver: ¿quién movió este mueble?
¿Recuerdas la nota del módulo 7 — "la plataforma CodeForge usa un MutationObserver para filtrar ruido de la consola de estos playgrounds"? Pues es hora de saber escribirlo:
Juega con los tres botones mirando la consola: la cámara reporta cada cambio SIN estar conectada a los botones — vigila el resultado, no las causas. Ese es su superpoder y su nicho: reaccionar a cambios que tu código no controla — lo que inyecta un script de terceros, lo que renderiza un framework ajeno, una extensión del navegador. Si el cambio lo haces TÚ, no te espíes con una cámara: llama a tu función directamente (o publica en tu bus del módulo 13) — más claro y más barato.
ResizeObserver: este salón cambió de tamaño
¿Y window.resize? Solo avisa del tamaño de LA VENTANA. Pero un elemento
cambia de ancho por mil razones más — y de eso avisa este:
const vigia = new ResizeObserver((entries) => {
for (const entry of entries) {
const ancho = entry.contentRect.width;
// el patrón: "container query" manual — clase según el ancho PROPIO
entry.target.classList.toggle("compacta", ancho < 400);
}
});
vigia.observe(document.querySelector(".tarjeta-resumen"));
// la tarjeta se adapta a SU espacio: en sidebar angosta, en main ampliaEl caso de uso estrella es ese: componentes que se adaptan a SU contenedor
y no a la ventana. Nota honesta doble: el CSS moderno ya trae container
queries nativas (@container, las viste en maquetación) que cubren el
caso visual sin JS — ResizeObserver queda para cuando la LÓGICA depende
del tamaño (recalcular un canvas, virtualizar una lista, redibujar un
gráfico). Y las gráficas que redibujan solas al cambiar el layout — ECharts,
Chart.js y compañía — llevan uno de estos adentro.
Un script de publicidad de terceros inyecta banners en tu página en momentos impredecibles y tú debes etiquetarlos apenas aparezcan. No puedes tocar el script. ¿Herramienta?
Mini-reto
Combina las cámaras: 1) al playground agrégale un <p id="contador"> que
un MutationObserver mantenga actualizado con "N gastos en lista" — sin
tocar los listeners de los botones (la cámara ES la fuente); 2) dale a la
lista resize: horizontal; overflow: auto; border: 1px solid en CSS
(la hace arrastrable del borde) y un ResizeObserver que la pinte de
.compacta bajo 300px; 3) reflexiona en un comentario: el contador,
¿era mejor con cámara o publicando en un bus propio? (No hay respuesta
única — hay trade-off: la cámara no se salta NINGÚN cambio; el bus es
explícito y barato.)
Qué sigue
Todos los observers trabajan fuera de tu hilo… pero tu CÓDIGO pesado sigue corriendo en el único cocinero del módulo 9 — y un cálculo de tres segundos congela la página, como sentiste en carne propia. La próxima lección contrata al segundo cocinero: Web Workers, JavaScript en un hilo aparte de verdad.