Syntax
new IntersectionObserver(callback, options).observe(element)Examples
Lazy-Loading Images
Loading an image only once it scrolls into view.
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
const img = entry.target;
img.src = img.dataset.src; // load the real image
observer.unobserve(img); // stop watching once loaded
}
});
});
document.querySelectorAll("img[data-src]").forEach(img => {
observer.observe(img);
});Triggering Animations on Scroll
Adding a class when an element becomes visible, with a threshold option.
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
entry.target.classList.add("fade-in");
}
});
}, { threshold: 0.5 }); // fires when 50% of the element is visible
document.querySelectorAll(".animate-on-scroll").forEach(el => {
observer.observe(el);
});Best practices
- Use IntersectionObserver instead of scroll event listeners for visibility detection - it is far more performant since the browser handles the calculation efficiently
- Call unobserve() once an element no longer needs watching (like after a lazy-loaded image has loaded), to free up resources
- Use the threshold option to control exactly what percentage of visibility should trigger the callback
- Use rootMargin to trigger the callback slightly before an element actually enters the viewport, for smoother lazy-loading
Runtime & versions
Browsers and JavaScript runtimes. Feature availability depends on the language and runtime version used by your project; consult the official reference below.
ECMAScript specification