---
title: "Tracking DOM Element Visibility"
description: "Using Intersection Observer API to efficiently track element visibility. Practical notes and code examples on Tracking DOM."
url: "https://h3manth.com/scribe/tracking-dom-element-visibility/"
canonical_url: "https://h3manth.com/scribe/tracking-dom-element-visibility/"
markdown_url: "https://h3manth.com/scribe/blog/tracking-dom-element-visibility.md"
publishDate: "2020-02-02T00:00:00.000Z"
author: "Hemanth HM"
category: "web"
tags: ["javascript","dom","performance"]
word_count: 204
reading_time_minutes: 2
x_markdown_tokens: 513
content_signal: "ai-train=yes, search=yes, ai-input=yes"
---

# Tracking DOM Element Visibility

> Using Intersection Observer API to efficiently track element visibility. Practical notes and code examples on Tracking DOM.

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

## The Old Way

We would normally apply a function like this to detect if an element is visible:

```javascript
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 scrolls, which is a costly operation.

## Intersection Observer API

That's where the [Intersection Observer API](https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API) comes to the rescue:

```javascript
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 and intersected
    console.log(change.intersectionRatio);  // Ratio of intersectionRect to boundingClientRect
    console.log(change.target);             // The Element target
  }
}, {});

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

// Stop watching
observer.unobserve(target);

// Stop observing
observer.disconnect();
```

## Example

Say, if we were to observe the element `#catBox` for visibility:

```javascript
let options = {
  root: document.querySelector('#catBox'),
  rootMargin: '0px',
  threshold: 1.0
}

let observer = new IntersectionObserver(callback, options);
```
