Get to know MDN better
Esta página ha sido traducida del inglés por la comunidad. Aprende más y únete a la comunidad de MDN Web Docs.
This feature is well established and works across many devices and browser versions. It’s been available across browsers since marzo de 2019.
* Some parts of this feature may have varying levels of support.
La API Observador de Intersección provee una vía asíncrona para observar cambios en la intersección de un elemento con un elemento ancestro o con el viewport del documento de nivel superior.
Históricamente, detectar la visibilidad de un elemento, o la visibilidad relativa de dos elementos, uno respecto del otro, ha sido una tarea difícil para la cual las soluciones no han sido muy fiables y propensas a causar que el navegador y los sitios a los que el usuario accede lleguen a ser lentos. A medida que la web ha madurado, la necesidad para este tipo de información ha ido en aumento. La información sobre intersección es necesaria por muchas razones, tales como:
Implementar la detección de intersecciones en el pasado implicaba manejadores de eventos y bucles llamando a métodos como Element.getBoundingClientRect() para reunir la información necesaria para cada elemento afectado. Dado que todo este código corre sobre el hilo principal, incluso uno de estos puede causar problemas de rendimiento. Cuando un sitio es cargado con estos tests, las cosas pueden ponerse muy feas.
Considere una página web que usa scroll infinito. Usa una librería de terceros para manejar los anuncios situados periódicamente en la página, que tiene gráficos animados aquí y allá, y usa una librería personalizada que muestra cajas de notificación y similares. Cada uno de estos tiene sus propias rutinas de detección de intersecciones, todas corriendo en el hilo principal. El autor del sitio web puede no darse cuenta de que esto está pasando, ya que están usando dos librerías de las que quizás conocen muy poco acerca de su funcionamiento interno. A medida que el usuario desplaza la página, estas rutinas de detección de intersecciones están disparando código constantemente durante el scroll, lo que resulta en una experiencia que deja al usuario frustrado con el navegador, el sitio web y su ordenador.
El API Intersection Observer deja al código registrar una función callback que se ejecuta si un elemento que se desea monitorizar entra o sale de otro elemento (o del viewport), o cuando la cantidad por la que ambos elementos se intersecan cambia en una cantidad requerida. De esta manera, los sitios no necesitan hacer nada sobre el hilo principal para mirar este tipo de intersección entre elementos, y el navegador está libre para optimizar la gestión de intersecciones como le parezca conveniente.
Una cosa que el API Intersection Observer no puede decirle es: el número exacto de pixels que se solapan o específicamente cuales son; sin embargo, cubre el caso de uso mucho más común de "Si se intersecan por algún lugar alrededor del N%, necesito hacer algo."
La API Intersection Observer le permite configurar una función callback que es llamada cuando alguna de las siguientes circunstancias ocurren:
Típicamente, usted querrá observar los cambios en las intersecciones con respecto al ancestro scrollable más cercano al elemento, o, si el elemento no desciende de un ancestro scrollable, al viewport. Para observar la intersección relativa al elemento root, especifique null;
Tanto si está usted usando el viewport o algún otro elemento como root, el API funciona de la misma manera, ejecutando una función callback que usted le proporciona cuando la visibilidad del elemento target cambia al cruzar en la cantidad de intersección deseada con el elemento root.
El grado de intersección entre el elemento target y su elemento root es el intersection ratio. Esto es una representación del porcentaje del elemento target que es visible, indicado como un valor entre 0.0 y 1.0.
Cree el intersection observer llamando a su constructor y pasándole una función callback para que se ejecute cuando se cruce un umbral (threshold) en una u otra dirección:
Un umbral de 1.0 significa que cuando el 100% del elemento target está visible dentro del elemento especificado por la opción root, la función callback es invocada.
El objeto options pasado al constructor IntersectionObserver() le deja controlar las circunstancias bajo las cuales la función callback es invocada. Tiene los siguientes campos:
rootEl elemento que es usado como viewport para comprobar la visibilidad de elemento target. Debe ser ancestro de target. Por defecto es el viewport del navegador si no se especifica o si es null.
rootMarginMargen alrededor del elemento root. Puede tener valores similares a los de CSS margin property, e.g. "10px 20px 30px 40px" (top, right, bottom, left). Los valores pueden ser porcentajes. Este conjunto de valores sirve para aumentar o encoger cada lado del cuadro delimitador del elemento root antes de calcular las intersecciones. Por defecto son todos cero.
thresholdEs un número o un array de números que indican a que porcentaje de visibilidad del elemento target, la función callback del observer debería ser ejecutada. Si usted quiere que se detecte cuando la visibilidad pasa la marca del 50%, debería usar un valor de 0.5. Si quiere ejecutar la función callback cada vez que la visibilidad pase otro 25%, usted debería especificar el array [0, 0.25, 0.5, 0.75, 1]. El valor por defecto es 0 (lo que significa que tan pronto como un píxel sea visible, la función callback será ejecutada). Un valor de 1.0 significa que el umbral no se considera pasado hasta que todos los pixels son visibles.
Una vez usted ha creado el observer, necesita darle un elemento target para observar:
Cuando el elemento target encuentra un threshold especificado por el IntersectionObserver, la función callback es invocada. La función callback recibe una lista de objetos IntersectionObserverEntry y el observer:
Asegúrese de que su función callback se ejecute sobre el hilo principal. Debería operar tan rápidamente como sea posible; si alguna cosa necesita tiempo extra para ser realizada, use Window.requestIdleCallback().
También, note que si especifica la opción root, el elemento target debe ser un descendiente del elemento root.
Todas las áreas consideradas por la API de Intersection Observer son rectángulos; los elementos que su forma es irregular se considera que están ocupando el rectángulo más pequeño que encierra todas las partes del elemento. De forma similar, si la porción visible de un elemento no es un rectángulo, entonces el rectángulo de intersección del elemento se interpreta como el rectángulo más pequeño que contiene todas las partes visibles del elemento.
Es útil entender un poco sobre cómo las diferentes propiedades proporcionadas por IntersectionObserverEntry describe una intersección.
Antes de poder realizar un seguimiento de la intersección de un elemento en un contenedor, necesitamos saber qué cuál es contendor. Este contenedor se le conoce como intersection root, o root element. Este puede ser un elemento del documento, que es ascendiente del elemento observado, o null, que usará el viewport del documento como contenedor.
El rectángulo usado como los límites de la intersección del intersection root pueden ser ajustados configurando la opción root margin, rootMargin, cuando creamos el IntersectionObserver. Los valores en rootMargin define los espacios añadidos a cada lado del cuadro delimitador que sirve de contenedor, creando los límites definitivos del contenedor, o intersection root (los cuáles están explicados en IntersectionObserverEntry.rootBounds cuando la función callback es ejecutada).
En lugar de reportar cada mínimo cambio indicando cómo de visible es el elemento que observamos, la Intersection Observer API usa umbrales. Cuando creamos un observable, puedes proporcionar uno o más valores númericos representando, en porcentaje, cuán visible es el elemento observado. Entonces, la API reporta sólo los cambios de visibilidad que cruza este umbral.
Por ejemplo, si te gustaría ser informado cada vez que la visibilidad del elemento pasa, hacia delante o hacía atrás, una marca de un 25%, entonces puedes especificar el array [0, 0.25, 0.5, 0.75, 1] como una lista de umbrales a la hora de crear el observable. Puedes saber incluso en qué dirección la visibilidad ha cambiado (esto es, saber si el elemento ha pasado a ser más o menos visible) comprobando el valor de la propiedad isIntersecting disponible en el IntersectionObserverEntry que tienes disponible en la función callback cada vez que la visibilidad cambia. Si isIntersecting es true, el elemento se ha vuelto al menos tan visibile como el umbral que pasó. Si es false, el elemento entonces ha dejado de ser tan visible como el umbral que sobrepasó.
Para entender cómo funciona el concepto de umbral (threshold), pruebe a hacer scroll en el siguiente ejemplo. Cada caja coloreada muestra dentro de ella el porcentaje que tiene visible de cada una de las cuadro esquinas, de forma que podrá ver cómo cambian los porcentajes conforme va haciendo scroll. Cada caja tiene diferentes valores configurado de umbrales.
El navegador computa el rectángulo de intersección final de la siguiente forma; la API hace todo esto por usted, pero puede ser útil entender estos pasos para comprender mejor cuando ocurrirán exactamente las intersecciones.
Cuando la cantidad del elemento target que es visible dentro del elemento root cruza uno de los umbrales de visibilidad, el callback del objeto IntersectionObserver es ejecutado. El callback recibe como input un array de todos los objetos IntersectionObserverEntry, uno por cada umbral que haya sido cruzado, y una referencia al objeto IntersectionObserver mismo.
Cada entrada en la lista de umbrales es un objeto IntersectionObserverEntry que describe un umbral que ha sido cruzado; esto es, cada entrada describe qué porción de un elemento dado se está intersectando con el elemento root, sea que el elemento se considere en intersección o no, y la dirección en la cual ocurrió la transición.
El siguiente fragmento de código muestra una devolución de llamada que mantiene un contador de cuántas veces los elementos hacen la transición desde no intersectar con la raíz hasta intersectar al menos en un 75%. Para un valor umbral de 0.0 (predeterminado), la devolución de llamada es lanzada aproximadamente cuando hay una transición en el valor booleano de IntersectionObserverEntry.isIntersecting. El fragmento de código primero verifica que la transición sea positiva y luego determina si IntersectionObserverEntry.intersectionRatio es superior al 75%; en ese caso, incrementa el contador.
intersectionCallback(entries) => { entries.forEach(entry => { if (entry.isIntersecting) { let elem = entry.target; if (entry.intersectionRatio >= 0.75) { intersectionCounter++; } } }); }La interfaz principal para la API de Observador de Intersecciones. Proporciona métodos para crear y gestionar un observador que puede vigilar cualquier número de elementos de destino para la misma configuración de intersección. Cada observador puede observar de manera asíncrona los cambios en la intersección entre uno o más elementos de destino (target) y un elemento ancestro compartido o con el viewport de su Document de nivel superior. El ancestro o el viewport se denomina root.
IntersectionObserverEntryDescribe la intersección entre el elemento de destino y su contenedor raíz en un momento específico de transición. Los objetos de este tipo solo se pueden obtener de dos maneras: como entrada para al devolución de llamada de tu IntersectionObserver, o llamando a IntersectionObserver.takeRecords().
Este ejemplo causa que el elemento que queremos observar cambia de color y transparencia conforme se va haciendo más o menos visible. En la página Timing element visibility with the Intersection Observer API, puedes encontrar un ejemplo más extenso que muestra cómo calcular cuanto tiempo que una serie de elementos, como anuncios, son visibles para el usuario y reaccionar a esa información guardando estadísticas.
El HTML para este ejemplo es muy simple, con un elemento primario que será la caja que querremos observar (con la creativa ID de "box") y algo de contenido para dentro de la caja.
El CSS del ejemplo no es muy importante para el propósito de este ejemplo: pinta el elemento y establece que los atributos background-color y border puedan participar en las CSS transitions, los cuáles usaremos para afectar los cambios al elemento conforme este es más o menos visible.
Finalmente, vamos a mirar el código JavaScript que usa la API Intersection Observer API para hacer que las cosas ocurran.
Primero, necesitamos preparar algunas variables e instalar el observador.
Las constantes y variables que establecimos aquí son:
numStepsUna constante que indica cuántos puntos de umbral queremos tener entre una proporción de visibilidad de 0.0 y 1.0.
prevRatioEsta variable se utilizará para registrar cuál era la proporción de visibilidad la última vez que se cruzó un umbral; esto nos permitirá determinar si el elemento de destino se está volviendo más o menos visible.
increasingColorUna cadena que define un color que aplicaremos al elemento de destino cuando la proporción de visibilidad esté aumentando. La palabra "ratio" en esta cadena será reemplazada por la proporción de visibilidad actual del objetivo, de modo que el elemento no solo cambie de color, sino que también se vuelva cada vez más opaco a medida que se oculta menos.
decreasingColorDe manera similar, esta es una cadena que define un color que aplicaremos cuando la proporción de visibilidad esté disminuyendo.
Llamamos a Window.addEventListener() para comenzar a escuchar el evento load; una vez que la página haya terminado de cargarse, obtenemos una referencia al elemento con el ID "box" utilizando querySelector(), luego llamamos al método createObserver() que crearemos en un momento para manejar la creación e instalación del observador de intersección.
El método createObserver() se llama una vez que la carga de la página se completa para manejar la creación real del nuevo IntersectionObserver y comenzar el proceso de observación del elemento de destino.
Comenzamos configurando un objeto options que contiene los ajustes para el observador. Queremos observar los cambios en la visibilidad del elemento de destino en relación con el viewport del documento, por lo que root es null. No necesitamos ningún margen, así que el desplazamiento del margen, rootMargin, se especifica como "0px". Esto hace que el observador vigile los cambios en la intersección entre los límites del elemento de destino y los del viewport, sin espacio adicional (o sustracción) alguno.
La lista de puntos de umbral de proporción de visibilidad, threshold, se construye mediante la función buildThresholdList(). En este ejemplo, la lista de umbrales se construye programáticamente, ya que hay varios de ellos y se pretende que el número sea ajustable.
Una vez que options está listo, creamos el nuevo observador llamando al constructor IntersectionObserver(), especificando una función que se llamará cuando la intersección cruce uno de nuestros umbrales, handleIntersect(), y nuestro conjunto de opciones. Luego, llamamos a observe() en el observador devuelto, pasándole el elemento de destino deseado (target).
Podríamos optar por vigilar los cambios de intersección de visibilidad con respecto al viewport en varios elementos llamando a observer.observe() para cada uno de esos elementos, si así lo deseamos.
La función buildThresholdList(), que construye la lista de umbrales, se ve así:
Esto construye el arreglo de umbrales, cada uno de los cuales es una proporción entre 0.0 y 1.0, al agregar el valor i/numSteps al arreglo thresholds para cada entero i entre 1 y numSteps. También agrega el valor 0 para incluirlo. El resultado, dado el valor predeterminado de numSteps (20), es la siguiente lista de umbrales:
| 1 | 0.05 | 11 | 0.55 |
| 2 | 0.1 | 12 | 0.6 |
| 3 | 0.15 | 13 | 0.65 |
| 4 | 0.2 | 14 | 0.7 |
| 5 | 0.25 | 15 | 0.75 |
| 6 | 0.3 | 16 | 0.8 |
| 7 | 0.35 | 17 | 0.85 |
| 8 | 0.4 | 18 | 0.9 |
| 9 | 0.45 | 19 | 0.95 |
| 10 | 0.5 | 20 | 1.0 |
Podríamos, por supuesto, codificar manualmente el arreglo de umbrales en nuestro código, y a menudo es lo que terminaremos haciendo. Pero este ejemplo deja espacio para agregar controles de configuración para ajustar la granularidad, por ejemplo.
Cuando el navegador detecta que el elemento de destino (en nuestro caso, el que tiene el ID "box") ha sido revelado u ocultado de tal manera que su proporción de visibilidad cruza uno de los umbrales en nuestra lista, llama a nuestra función de manejo, handleIntersect():
Para cada IntersectionObserverEntry en la lista entries, verificamos si intersectionRatio del registro está aumentando; si es así, establecemos background-color del elemento de destino con la cadena increasingColor (recuerda, es "rgba(40, 40, 190, ratio)"), reemplazando la palabra "ratio" con el valor de intersectionRatio del registro. El resultado: no solo cambia el color, sino que también cambia la transparencia del elemento de destino; a medida que la proporción de intersección disminuye, el valor alfa del color de fondo también disminuye, lo que resulta en un elemento más transparente.
De manera similar, si intersectionRatio está aumentando, usamos la cadena decreasingColor y reemplazamos la palabra "ratio" en esa cadena con el valor de intersectionRatio antes de establecer background-color del elemento de destino.
Finalmente, para rastrear si la proporción de intersección está aumentando o disminuyendo, recordamos la proporción actual en la variable prevRatio.
Abajo se encuentra el contenido resultante. Desplace ésta página hacia arriba y abajo y note como la apariencia de la caja cambia mientras lo hace.
Hay un ejemplo aún más extensivo en Cronometrando la visibilidad de un elemento con la API Intersection Observer.
| Intersection Observer # intersection-observer-interface |
Enable JavaScript to view this browser compatibility table.
This page was last modified on 31 mar 2026 by MDN contributors.
Your blueprint for a better internet.
Visit Mozilla Corporation’s not-for-profit parent, the Mozilla Foundation.
Portions of this content are ©1998–2026 by individual mozilla.org contributors. Content available under a Creative Commons license.