IntersectionObserver Playground

The browser tells you, for free, when any element enters or leaves the viewport — no scroll listeners, no layout thrash. Scroll down: the dashed boxes light up the moment they cross your visibility threshold, and every crossing is logged.

Then try the A/B test demo: it only enrolls you in the experiment after the test content scrolls into view — which is how you stop counting people who never saw your variant.

// 1. the observer, live

threshold = how much of a box must be on screen before it counts as "seen": 0% fires the moment a single pixel appears, 100% only when the whole box is visible. rootMargin grows or shrinks the watched area — try "-100px" to pull the edges inward.

event log

▼ scroll — box-1 is below ▼
box-1
▼ box-2 ▼
box-2
▼ box-3 ▼
box-3
▼ box-4, then the A/B test ▼
box-4

// 2. honest A/B tests: enroll on visibility

The classic A/B testing mistake: your variant lives halfway down the page, but you enroll every page load into the test. Visitors who bounced before ever seeing the variant count as non-converters — diluting your numbers and hiding real winners. The fix is one observer: enroll a visitor only when the experiment zone actually enters their viewport.

live enrollment

VARIANT A

Try it free for 14 days

VARIANT B

Get started in 30 seconds

↑ scroll this zone into view to get enrolled (threshold 0.5) ↑

your session

metricvalue
assigned variant— (not enrolled yet)
enrolled at
conversions0

// 3. the pattern in 10 lines

// enroll a visitor only when the experiment zone is actually seen
const io = new IntersectionObserver((entries) => {
  for (const e of entries) {
    if (e.isIntersecting) {
      enrollInExperiment(e.target.dataset.variant);
      io.unobserve(e.target); // count each visitor once
    }
  }
}, { threshold: 0.5 });

io.observe(document.querySelector('#experiment-zone'));

The callback runs off the main thread's layout work — unlike a scroll handler, it never forces the browser to recalculate styles to answer "is this visible?". That's why it's the right tool for lazy-loading images, infinite scroll, impression tracking, scroll-spy navs — and gating experiment enrollment on actual visibility.