The beauty of IntersectionObserver API

Hardik khanchandani
Tech @ Trell
Published in
5 min readDec 23, 2021

Introduction

IntersectionObsever API is not new to us. But I still feel that this API is under-used, it has many powerful applications on the web.

In this blog, I will discuss how we use IntersectionObserver at Trell and I will try to dig deeper into this API in follow-up blogs.

Wait! I don’t know what an IntersectionObserver is… 😕

Well, it has “Intersection” in its name. So guess what, it is used to know if an element is intersecting with the screen or not, in other words, if an element is visible on-screen or not. So it just observes that.

Cool, but why do we want to observe if an element is on screen?

Well, there are many use-cases for which we want to observe elements, few of them are following:

1. Pagination in Infinite Scroll

It’s great for network optimization, to load data in chunks, when a user is about to reach the end of the first page, we will append the next page below it. Maybe it’s a topic of another blog 😺

Design by Astha Oberoi

2. Lazy Loading Images

Well, this isn’t a new concept, even Medium uses it in a great way, Kudos. You must have noticed first we see the blurry image and later it gets loaded when it’s on-screen, here what we can do is first pass the degraded image src with a blur filter, after when the image is intersecting with the screen we can replace its src with quality image link, by this way we reduce the initial loading time of web page.

3. Analytics

We would want to know, how many impressions our features are receiving, and how many times they saw it, or maybe for how long they keep starring at it. This gives us great feedback on how our new feature is performing.

For Example for Trell: How many people have seen our new Best Sellers Section and how many times, are they ignoring it or spending good enough time with it.

4. Scroll Navigation ( Trell’s New Brand Navigation )

You must have seen A-Z scroll navigation on your contacts list on mobile, well that’s what I’m talking about, but for brands. It is a great UX improvement since brands are increasing on Trell. I have been developing this feature, it gave me a lot of learnings.

The idea is simple for this, we will add IntersectionObservers to each section, from A-Z. Whenever a section is on screen, we update other components (Number of brands with that letter and active Letter on the right side)for the same.

Great!! Enough of use-cases, tell me how to implement?

The Intersection Observer API provides a way to asynchronously observe changes in the intersection of a target element with an ancestor element or with a top-level document’s viewport. — MDN Docs

Creating Observer

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

let observer = new IntersectionObserver(callback, options);

You can see how observer Instance is made from the above code. But the thing to discuss is options.

root: Root is the element that is used as a viewport for checking the visibility or intersection. Default is null which is Window as a viewport. You can pass scrollRef.current if you are using react with the help of useRef Hook.

rootMargin: Just like CSS Margin this is the Margin around the root element. default is 0px. In short, if I do “20px 0px 0px 0px" (top, right, bottom, left) The callback will be triggered 20px before the element starts intersecting with the viewport while scrolling down.

threshold: Threshold can be a number or array of numbers, 1 means Trigger callback when 100% of the target is visible on the screen. Array may include numbers like [0, 0.25, 0.5, 0.75, 1] meaning trigger callback at 0% ( Event one pixel of the target is on the screen) 25%, 50%, 75% and 100% respectively.

When Target Satisfies the threshold, the callback will be invoked

let callback = (entries, observer) => {
entries.forEach(entry => {
if( entry.isIntersecting ){
// element is Intersecting
}
else // element is now out of screen
});
};

Keep in mind that callback will be triggered when an element is out of the screen or loses threshold value. Have a look at what other properties does the entries array has on MDN Docs IntersectionObserverEntry.

Cool, I’m using React, can we make a Hook…? Yes

I love Hooks ❤

Hooks implementation of Intersection observer

You can play with it here.

Explanation: Initially ref.current is null, so we don’t want to observe it. We will start observing when ref.current is assigned to an element, initializeObserver function returns a new instance of IntersectionObserver, but not so fast, few browsers don’t support it out of the box. We are loading polyfill conditionally so that we don’t load unused JavaScript on the client. See Cost of JavaScript. Also, you may want to use IntersectionObserver Polyfill. In case it’s not supported on the browser.

You can modify according to your need, maybe you want to pass custom options and a callback to this hook, which is a great extension of the above hook.

You can use it like the below example.

Using useIsIntersecting Hook

Resources

  1. IntersectionObserver Polyfill
  2. MDN Reference to IntersectionObserver API
  3. Build Your Own Hook in React
  4. NPM Package for polyfill
  5. Basic Introduction of Intersection Observer (Video)

Thanks to my seniors, Hitesh and Aniket for reviewing and suggesting improvements in the blog :) ❤

Designs by Astha

Thanks for Reading, Happy Coding! 🤠

--

--