Script Valley
JavaScript in the Browser: DOM, Events & APIs
Styles, Classes, and Layout via JavaScriptLesson 3.5

Intersection Observer: detecting when elements enter the viewport

IntersectionObserver API, threshold, rootMargin, isIntersecting, lazy loading pattern, infinite scroll, disconnect

Intersection Observer

The IntersectionObserver API fires a callback when an observed element enters or leaves the viewport — without scroll event listeners or getBoundingClientRect polling.

const observer = new IntersectionObserver((entries) => {
  entries.forEach(entry => {
    if (entry.isIntersecting) {
      entry.target.classList.add('visible');
      observer.unobserve(entry.target); // stop watching after first trigger
    }
  });
}, {
  threshold: 0.2,    // fire when 20% of element is visible
  rootMargin: '0px'  // no pre-emptive margin
});

document.querySelectorAll('.fade-in').forEach(el => observer.observe(el));

Lazy Loading Images

const imgObserver = new IntersectionObserver((entries) => {
  entries.forEach(({ isIntersecting, target }) => {
    if (isIntersecting) {
      target.src = target.dataset.src;
      imgObserver.unobserve(target);
    }
  });
});
document.querySelectorAll('img[data-src]').forEach(img => imgObserver.observe(img));

Call observer.disconnect() to stop observing all elements at once. IntersectionObserver runs off the main thread and does not trigger reflows — it is significantly more performant than scroll-event alternatives.