JAVASCRIPT
Detect Element Visibility with useIntersectionObserver
Create a useIntersectionObserver React hook to efficiently detect when a DOM element enters or exits the viewport, enabling lazy loading or scroll-based animations.
import { useRef, useState, useEffect } from 'react';
function useIntersectionObserver(options) {
const [entry, setEntry] = useState(null);
const targetRef = useRef(null);
useEffect(() => {
const currentRef = targetRef.current;
if (!currentRef) return;
const observer = new IntersectionObserver(([ent]) => {
setEntry(ent);
}, options);
observer.observe(currentRef);
return () => {
observer.unobserve(currentRef);
};
}, [options]); // Re-run if options change, though often options are static
return [targetRef, entry];
}
/*
// Example usage:
function LazyImage({ src, alt }) {
const [imgRef, entry] = useIntersectionObserver({ threshold: 0.1 });
const isVisible = entry?.isIntersecting;
return (
<img
ref={imgRef}
src={isVisible ? src : undefined}
alt={alt}
style={{ minHeight: '200px', background: 'lightgray', transition: 'opacity 0.5s', opacity: isVisible ? 1 : 0.5 }}
/>
);
}
// To use LazyImage in a component:
// function MyGallery() {
// return (
// <div style={{ height: '200vh', overflowY: 'scroll' }}>
// <h2>Scroll down to see images load!</h2>
// <div style={{ height: '80vh' }}></div>
// <LazyImage src="https://via.placeholder.com/150/FF0000/FFFFFF?text=Image+1" alt="Placeholder Image 1" />
// <div style={{ height: '80vh' }}></div>
// <LazyImage src="https://via.placeholder.com/150/0000FF/FFFFFF?text=Image+2" alt="Placeholder Image 2" />
// </div>
// );
// }
*/
How it works: This useIntersectionObserver hook provides a way to detect when a component (or any DOM element) enters or leaves the viewport. It returns a `ref` to attach to the target element and an `entry` object from the Intersection Observer API. The `entry.isIntersecting` property can then be used to determine visibility. This is highly efficient for implementing features like lazy loading images, infinite scrolling, or triggering animations when elements become visible.