Javascript. Intersection Observer
Introducción a la API Intersection Observer de Javascript
Hoy os quiero hacer una introducción a una de esas API’s de Javascript cuya existencia suele ser desconocida pero que ayuda a resolver gran cantidad de problemas y situaciones empleando código nativo: la API Intersection Observer.
La API Intersection Observer nos permite observar de forma asíncrona los cambios producidos en la intersección entre el elemento observado y un elemento superior (o el propio viewport).
Así que sin entretenernos más, ¡vamos a ver cómo usarla!
Introducción
Históricamente, detectar cuando un elemento pasaba a ser visible en el viewport era una tarea bastante complicada si no costosa de implementar cuando recurríamos a librerías de terceros. Por ejemplo, este tipo de información era necesaria si queríamos cargar imágenes de forma lazy, implementar el típico scroll infinito o mostrar anuncios al llegar a determinadas partes de la web.
Todas estas tareas que antiguamente implicaban bucles ejecutándose constantemente y llamadas a métodos como getBoundingClientRect
pueden ser implementadas de forma mucho más sencilla gracias a esta API.
Por cierto, esta API según caniuse.com está soportada por casi un 90% de los navegadores, por lo que en general podréis emplearla (siempre y cuando estéis dispuestos a olvidados de nuestro querido Internet Explorer):

La API Intersection Observer
Para comenzar a emplear Intersection Observer lo primero que haremos será crear un objeto IntersectionObserver
:
let observer = new IntersectionObserver(callback, options);
Este objeto recibe dos argumentos:
- Una función
callback
que será ejecutada cuando el umbral que especifiquemos enoptions
sea traspasado. - Un objeto
options
en el cual podremos especificar la forma en que queremos que funcione nuestro observer.
Por ejemplo, el objeto options
puede tener la siguiente forma:
const options = {
root: document.querySelector('#main-container'),
rootMargin: '10px 0px', // like css property
threshold: 1.0
}
- La propiedad
root
especifica que elemento deberá emplear el observer para comprobar la intersección. En el caso de que no lo especifiquemos se tomará por defecto el viewport del navegador. - La propiedad
rootMargin
especifica el margen alrededor del elementoroot
de modo que podamos alargar o estrechar los lados del elementoroot
a la hora de realizar la comprobación. - Finalmente la propiedad
threshold
especifica en qué porcentaje de la visibilidad del elemento observado se debe ejecutar elcallback
. Por ejemplo, si queremos detectar cuando se ha traspasado el 50% especificaremos unthreshold
con valor0.5
. En nuestro caso, el valor1.0
indica que el umbral no se considera traspasado hasta que todos los píxeles del elemento sean visibles.
Una vez que ya tenemos creado nuestro observer, podemos emplearlo para observar cualquier elemento del DOM, por ejemplo:
let target = document.querySelector('#itemId');
observer.observe(target);
De modo que, cuando se cumpla la condición que hayamos especificado el callback será ejecutado. Esta función recibe dos argumentos:
- Una lista de objetos
IntersectionObserverEntry
. - El propio objeto
observer
Y dentro de ella podremos realizar las acciones que necesitemos, eso sí, teniendo en cuenta que su ejecución sucede en el main thread, de modo que deberemos evitar realizar operaciones pesadas dentro de ella si no queremos bloquear la interfaz.
Lazy loading para imágenes
Un ejemplo de cómo podemos emplear la API Intersection Observer es para cargar nuestras imágenes de forma lazy conforme se van mostrando en el DOM.
Para ello, partiremos primero del siguiente HTML:

Como veis, cada imagen tiene el atributo src
puesto a un determinado placeholder y un atributo data-src
donde se encuentra la imagen original que mostraremos de forma lazy.
A continuación, definiremos la función que queremos ejecutar como callback de nuestro Intersection Observer. Esta función lo que hará será modificar el atributo src
por el valor del atributo data-src
de modo que se cargue la imagen correspondiente.
Tal y como vimos anteriormente, el callback de Intersection Observer recibe dos argumentos, entries
(con los objetos que dispararon el evento) y observer
. Lo que haremos será iterar sobre el array entries
de cara a realizar la operación de carga de la imagen.

Lo más reseñable de este callback es los siguiente:
- En primer lugar estamos comprobando si se ha detectado la intersección del objeto con el elemento padre (en este caso el viewport) para lo cual empleamos la propiedad
isIntersecting
. - En caso afirmativo, modificamos la propiedad
src
del elemento y empleamos el objetoobserver
para dejar de observarlo, pues la operación sólo queremos que se ejecute una vez para cada imagen.
Hecho esto, lo siguiente será declarar nuestro objeto IntersectionObserver
, para lo cual haremos lo siguiente:

El código en este caso es bastante sencillo, lo que hacemos es pasar al constructor el callback definido anteriormente y el objeto de opciones, en donde establecemos la propiedad rootMargin
con un valor de 200px
para el margen inferior, de modo que el evento se dispare cuando todavía queden 200 píxeles para que aparezca la imagen de modo que el usuario no se “entere” de esa carga en diferido.
Finalmente, lo que haremos será seleccionar todas nuestras imágenes y decirle al objeto observer
que las observe mediante su método observe
:

Con esto nuestras imágenes comenzarán a cargar de forma lazy a medida que hagamos scroll. ¡Y todo ello de forma nativa!
El código de este ejemplo podéis verlo en el siguiente Code Pen por si queréis seguir explorando esta API que nos proporcionan los navegadores.
Conclusiones
Como habéis podido ver, la API Intersection Observer nos permite resolver de forma nativa situaciones o problemas que anteriormente nos obligaban a recurrir a librerías de terceros.
Por tanto, espero que este artículo además de serviros a modo de introducción para esta característica, también os anime a profundizar un poco más en todas las API’s nativas que nos proporciona Javascript de modo que no tengamos que recurrir por norma a soluciones de terceros.
¿Quieres recibir más artículos como este?
Si te ha gustado este artículo te animo a que te suscribas a la newsletter que envío cada domingo con publicaciones similares a esta y más contenido recomendado: 👇👇👇