IntersectionObserver PolyfillLoading saved progress…

IntersectionObserver Polyfill

IntersectionObserver powers lazy-loaded images, infinite scroll, and "viewed" analytics by telling you when an element enters or leaves the viewport — efficiently, off the main thread. On older browsers you fake it the old-fashioned way: listen to scroll and resize, measure each watched element with getBoundingClientRect(), and fire when its on-screen status flips. Building that fallback shows exactly what the native API hides.

Implement intersectionObserverPolyfill(callback, options) returning an observer with observe, unobserve, and disconnect, matching the real API's shape. See MDN: IntersectionObserver.

Signature

function intersectionObserverPolyfill(callback, options) {
  return { observe, unobserve, disconnect };
}
// callback(entries, observer); entry =
//   { target, isIntersecting, intersectionRatio, boundingClientRect }

Examples

const io = intersectionObserverPolyfill((entries) => {
  for (const e of entries) if (e.isIntersecting) load(e.target);
});
io.observe(image);   // fires an initial entry immediately
// ...user scrolls; when `image` enters the viewport, the callback runs again
io.disconnect();     // detaches scroll/resize listeners

Notes

  • Measure against the viewport — the box is (0, 0, window.innerWidth, window.innerHeight); an element intersects when its rect overlaps it.
  • Fire on change, not every tick — track each element's last isIntersecting; only report the ones that flipped on a given scroll/resize.
  • Initial entryobserve(el) delivers one entry right away with the element's current state, like the native observer.
  • intersectionRatio — the fraction of the element's area that's visible (0 when off-screen, 1 when fully in view). Clean up listeners in disconnect.
Loading editor…