Intersection Observer API
Intersection Observer watches when elements enter or leave the viewport — perfect for lazy loading images, infinite scroll, scroll animations, and tracking impressions. Much more efficient than scroll event listeners.
Intersection Observer
- new IntersectionObserver(callback, options) — Create observer
- observer.observe(element) — Start watching an element
- callback receives entries — entry.isIntersecting = true when visible
- options.threshold — How much visible to trigger: 0 (any pixel), 0.5 (50%), 1 (100%)
- options.rootMargin — Offset: '100px' triggers 100px before entering viewport
- Use cases — Lazy load images, infinite scroll, fade-in animations, ad impression tracking
Intersection Observer Code
// Lazy loading images
const imageObserver = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
const img = entry.target;
// img.src = img.dataset.src; // load actual image
console.log("Image visible:", img.alt || "image");
imageObserver.unobserve(img); // stop watching (loaded)
}
});
}, {
rootMargin: "100px", // load 100px before reaching viewport
threshold: 0
});
// Observe all lazy images
// document.querySelectorAll("img[data-src]").forEach(img => {
// imageObserver.observe(img);
// });
// Scroll animations — fade in on scroll
const animObserver = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
entry.target.classList.add("visible");
console.log("Element visible:", entry.target.className);
// animObserver.unobserve(entry.target); // animate only once
}
});
}, { threshold: 0.2 }); // trigger when 20% visible
// Infinite scroll — load more when reaching end
const sentinelObserver = new IntersectionObserver((entries) => {
if (entries[0].isIntersecting) {
console.log("Loading more items...");
// loadMoreItems();
}
});
// sentinelObserver.observe(document.querySelector("#load-more-sentinel"));
console.log("Intersection Observer patterns demonstrated");Tip
Tip
Use Intersection Observer for lazy loading images, infinite scroll, and scroll-based animations. It's much more performant than scroll event listeners because it uses the browser's internal optimization rather than JavaScript.
Efficient scroll detection.
Common Mistake
Warning
Not disconnecting observers when they're no longer needed. Call observer.disconnect() or observer.unobserve(element) to clean up. In React, do this in the useEffect cleanup function.
Practice Task
Note
Observers: (1) Create a lazy image loader that loads images only when they scroll into view. (2) Build a sticky header that changes style when scrolled past a threshold. (3) Track which sections the user has read.
Quick Quiz
Key Takeaways
- Intersection Observer watches when elements enter or leave the viewport — perfect for lazy loading images, infinite scroll, scroll animations, and tracking impressions.
- new IntersectionObserver(callback, options) — Create observer
- observer.observe(element) — Start watching an element
- callback receives entries — entry.isIntersecting = true when visible