JavaScript de Cero a Experto / APIs del navegador
IntersectionObserver: el portero que avisa
"Anima esta tarjeta cuando entre en pantalla", "carga la imagen solo
cuando se acerque", "marca el capítulo que el lector va leyendo" — todo
eso exige saber cuándo un elemento se VE. La solución ingenua (espiar el
scroll y medir posiciones sin parar) castiga el rendimiento; el navegador
trae una API dedicada que lo hace gratis: IntersectionObserver.
El portero del cine
Baja por el preview y mira las tarjetas revelarse al entrar (y la consola
narrar los cruces). Anatomía: el constructor recibe TU reacción — que se
ejecuta con un array de entries, una por elemento que cruzó — y las
opciones; cada entry trae target (quién) e isIntersecting (¿está
adentro?). Con observe(elemento) lo pones en la lista del portero;
unobserve lo saca. Y fíjate en los dos oficios repartidos como manda el
módulo 7: JS pone la clase, el CSS anima (con su prefers-reduced-motion,
innegociable).
Los dos patrones y el dial de opciones
Revelar una vez (el del playground): al entrar, clase + unobserve —
el portero no gasta ni un aviso más en tarjetas ya reveladas. Es el patrón
de las animaciones de entrada y del lazy loading de imágenes (asignar el
src real solo al acercarse).
Vigilancia continua (sin unobserve): entradas Y salidas te llegan
siempre — con eso se construye el "capítulo activo" de los índices
laterales (como el de estas lecciones), autoplay de videos al verse, o
pausar un juego al salir de pantalla.
El dial fino de opciones: threshold puede ser un array
([0, 0.5, 1] = avísame al asomar, a la mitad y completo), y
rootMargin: "200px" agranda la "puerta" — el aviso llega 200px ANTES de
que el elemento entre, el truco del lazy loading que nadie nota (la imagen
ya cargó cuando llegas a ella).
¿Y el viejo mundo? Escuchar scroll + medir posiciones se dispara decenas
de veces por segundo EN tu hilo (el cocinero del módulo 9 interrumpido sin
piedad); el observer evalúa en el motor del navegador y te llama solo en
los cruces. Nota honesta: para efectos que dependen del scroll CONTINUO
(parallax, barras de progreso de lectura), el observer no basta — ahí sí
se escucha scroll con cabeza, o se usa ScrollTrigger de GSAP como en
SC-01, que por dentro combina ambas cosas.
Tu página de recetas tiene 200 fotos y quieres cargarlas solo cuando el usuario se acerque a cada una. ¿Cuál es el plan correcto?
Mini-reto
Sobre el playground: 1) cambia el threshold a [0, 1] y estudia en la
consola la diferencia entre "asomó" y "se ve completa"; 2) quita el
unobserve y observa los avisos de SALIDA al subir y bajar (vigilancia
continua); 3) construye el marcador: un <p id="viendo"> fijo que
muestre el texto de la última tarjeta que entró — el mecanismo exacto del
"capítulo activo" de este sitio que estás usando ahora mismo.
Qué sigue
El portero vigila la puerta de la PANTALLA. Sus dos hermanos vigilan otra
cosa: cambios en el propio DOM (MutationObserver — ¿quién movió este
mueble?) y cambios de tamaño (ResizeObserver — este salón se encogió).
Próxima lección: las cámaras de seguridad del DOM.