TIL: IntersectionObserver Class in JavaScript
Tags: javascript
Published: 2021-04-18 17:24:42

Okay, this was a few days ago, but 🤷🏻‍♂️.

Over the last week, I've been devouring [The Complete JavaScript Course](https://www.udemy.com/course/the-complete-javascript-course/) as a way to 1. Get over my fear of JavaScript (that's a post for a later time) and 2. Ensure my current carrer as a WordPress developer doesn't stay stuck in the pre-Gutenberg world (that's also another tale for another time).  The course itself was fantastic, and has put me in a better place mentally and emotionally to take on JS/Gutenberg projects.

There was one section that I wanted to write about today.  It's a feature that I’d never heard of before and would solve some past issues I've seen at work regarding components of a websites sliding into view and triggering an action.

It’s the ✨ IntersectionObserver ✨ class.

The JavaScript [IntersectionObserver](https://developer.mozilla.org/en-US/docs/Web/API/IntersectionObserver) class (which is part of the [Intersection Observer API](https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API)) can be used to indicate when a portion of a website scrolls a specified distance down the page or within reach of an element:

From there, you can do wonderful things:

- Set the navigation bar to stick to the top of the page when scrolling past a certain point.
- Lazy load images when or before the come into view.
- Ease sections into view on scroll.

<a href="https://assets.hirozed.xyz/viewport.png"></a><img alt="Screen capture of browser to illustrate the nav reaching a portion of the page." src="https://assets.hirozed.xyz/viewport.png" width="80%"/></a>

Below is an example of a sticky navigation from the class’s Github repository:

[The Complete JavaScript Course - section 13: Advanced DOM and Events](https://github.com/jonasschmedtmann/complete-javascript-course/blob/master/13-Advanced-DOM-Bankist/final/script.js#L137-L156) credit [Jonas Schmedtmann](https://codingheroes.io/).

```javascript
// Sticky navigation: Intersection Observer API

// Get the first section of content based on the .header class
const header = document.querySelector('.header');

// Get the height of the navigation bar
const navHeight = nav.getBoundingClientRect().height;

// Add or remove the sticky class to the nav bar,
// based on the entries retrieved from the IntersectionObserver class.
const stickyNav = function (entries) {
  // There is only one header, so we don't need to loop,
  // and can deconstruct the array.
  const [entry] = entries;

  // This is where the magic happens.
  // When the header is past the viewport, add the sticky class.
  // Else, when it comes back into view, remove the class.
  if (!entry.isIntersecting) nav.classList.add('sticky');
  else nav.classList.remove('sticky');
};

// Calling the IntersectionObserver class.
const headerObserver = new IntersectionObserver(stickyNav, {
  root: null, // Declaring null uses the entire viewport.
  threshold: 0, //  The percentage of the header to come into view.
  rootMargin: `-${navHeight}px`, // The offset based on the nav bar's height.
});

// Get some popcorn, the fun is about to start.
headerObserver.observe(header);
```
I also want to point out [`getBoundingClientRect`](https://developer.mozilla.org/en-US/docs/Web/API/Element/getBoundingClientRect). This function provides the size of an element and where it's located in relation to the viewport.  In the example above, Jonas only uses the height value, but you can grab the size and the distance from the viewport as well.

Learning about the Intersection Observer API was an unexpected and exciting piece of the huge amount of information I downloaded into my brain. I can see using the API as a much more reliable method for detecting when sections of the site come into and out of view, and replacing a placeholder with a higher quality image.  Causing text to zoom in when the container div scrolls into view.  The possibilities are endless!