Detecta si un elemento es visible en el viewport. Perfecto para lazy loading, animaciones al scroll y paginación infinita.
Detecta cuando un elemento entra o sale del viewport usando la API IntersectionObserver. Se actualiza automáticamente cuando el elemento se vuelve visible o invisible.
import { useIntersectionObserver } from "@blifedesarrollo/hooks";function ScrollIndicator() {
const { ref, inView } = useIntersectionObserver();
return (
<div>
<div className="h-screen">Contenido arriba</div>
<div ref={ref}>
<p>{inView ? "✅ Visible" : "❌ No visible"}</p>
</div>
</div>
);
}Cómo funciona:
ref → Asigna esta referencia al elemento que quieres observarinView → true si el elemento está visible, false si noentry → Objeto con información detallada de la intersecciónfunction LazyImage({ src, alt }) {
const { ref, inView } = useIntersectionObserver();
return (
<div ref={ref}>
{inView ? (
<img src={src} alt={alt} />
) : (
<div className="w-full h-64 bg-gray-200">Cargando...</div>
)}
</div>
);
}function AnimatedSection() {
const { ref, inView } = useIntersectionObserver();
return (
<div
ref={ref}
className={`transition-opacity duration-500 ${inView ? "opacity-100" : "opacity-0"}`}
>
<h2>Contenido que aparece al hacer scroll</h2>
</div>
);
}function Section() {
// Solo se considera visible cuando está 100% visible
const { ref, inView } = useIntersectionObserver({
threshold: 1, // 0 = cualquier parte visible, 1 = completamente visible
});
return <div ref={ref}>{inView ? "Completamente visible" : "Parcialmente visible"}</div>;
}function Section() {
// Se considera visible 100px antes de entrar al viewport
const { ref, inView } = useIntersectionObserver({
rootMargin: "100px", // Precarga antes de ser visible
});
return <div ref={ref}>{inView ? "Visible o cerca" : "Lejos"}</div>;
}| Parámetro | Tipo | Descripción |
|---|---|---|
options | IntersectionObserverInit | Opciones opcionales (ver abajo) |
| Opción | Tipo | Default | Descripción |
|---|---|---|---|
root | Element | null | null | Elemento viewport (null = viewport del navegador) |
rootMargin | string | - | Margen alrededor del root (ej: "100px") |
threshold | number | number[] | 0 | Porcentaje de visibilidad (0-1) |
Ejemplos de threshold:
0 → Se dispara cuando cualquier parte es visible0.5 → Se dispara cuando el 50% es visible1 → Se dispara solo cuando está completamente visible[0, 0.5, 1] → Se dispara en múltiples puntos| Valor | Tipo | Descripción |
|---|---|---|
ref | (node: HTMLElement | null) => void | Referencia a asignar al elemento a observar |
inView | boolean | true si el elemento está visible |
entry | IntersectionObserverEntry | null | Información detallada de la intersección |