Hemanth.HM

A Computer Polyglot, CLI + WEB ♥'r.

Tracking DOM Element Visibility

| Comments

We would normally track if a DOM element is visible in the viewport or not to understand user behaviour or to operate on the elment based on visibilty (animation, ajax calls etc).

We would normally apply a function like below to detect if an element is visible in the viewport:

1
2
const isInView = (elm, {top, height} = elm.getBoundingClientRect()) =>
    top <= innerHeight && top + height >= 0;

Later we would mostly add it on scroll events to trigger the checks as the user scroll, which in turn is a costly operation.

That's where the Intersection Observer API comes into rescue.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// From the spec
const observer = new IntersectionObserver(changes => {
  for (const change of changes) {
    console.log(change.time);               // Timestamp when the change occurred
    console.log(change.rootBounds);         // Unclipped area of root
    console.log(change.boundingClientRect); // target.boundingClientRect()
    console.log(change.intersectionRect);   // boundingClientRect, clipped by its containing block ancestors, and intersected with rootBounds
    console.log(change.intersectionRatio);  // Ratio of intersectionRect area to boundingClientRect area
    console.log(change.target);             // the Element target
  }
}, {});

// Watch for intersection.
observer.observe(target);

// Stop watching.
observer.unobserve(target);

// Stop observing.
observer.disconnect();

Say, if we were to observe this element, #catBox for visiblity, we would end up with:

1
2
3
4
5
6
7
let options = {
  root: document.querySelector('#catBox'),
  rootMargin: '0px',
  threshold: 1.0
}

let observer = new IntersectionObserver(callback, options);

Comments