Do something when an element scrolls into view

Lazy loading, fade-ins and "read" markers without a scroll listener.

SNP 072 #935 Filed js webdev

javascript
const observer = new IntersectionObserver(
  (entries) => {
    for (const entry of entries) {
      if (!entry.isIntersecting) continue
      entry.target.classList.add('is-visible')
      observer.unobserve(entry.target)
    }
  },
  { rootMargin: '0px 0px -10% 0px', threshold: 0.1 }
)

document.querySelectorAll('.card').forEach((card) => observer.observe(card))

threshold: 0.1 fires when a tenth of the element shows; the negative bottom rootMargin waits until it is a bit inside the viewport instead of right at the edge. Unobserving after the first time keeps it from running on every scroll.

Scroll listeners run on every pixel of scrolling; the observer only calls you when something crosses the line, which is why it is the right tool for this.