Intersection Observer API in JavaScript
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.
In short, an Intersection Observer provides a way to observe any element on the page and do something when it’s partially displayed, completely displayed, or is about to get displayed.
This is useful in a variety of situations like
1. Start or stop animation on scroll
2. Lazy load images on scroll
3. Automatically play or pause videos on scroll
4. Analyze if an ad is displayed or not and how many times it’s viewed
5. Identify when something is getting displayed or hidden from the viewport
And the possibilities are endless as you can do many difficult things easily now just using Intersection Observer.
Create an Intersection Observer
To create an Intersection Observer, we call the constructor by providing two parameters
• Callback function to be executed when an element is observed
• Optional options which specify when the callback will be called
Then we add the elements of the page we want to observe
Take a look at below demo
As you can see, on page load, only box1 is visible so visible for box1, and for other boxes invisible is displayed in the console.
When you scroll the page, as soon as the second box is getting displayed, visible is displayed for it in the console and as you keep scrolling, for the boxes which are not displayed invisible will be displayed.
Take a look at the code for the above demo.
Here, initially, we are selecting all the boxes on the page.
const boxes = document.querySelectorAll(‘.box’);
Then we are creating an Intersection Observer by passing it a callback function as the first argument.
So now, whenever any element is displayed or get’s hidden on the viewport (which is a browser by default), the callback handler will be called and entries parameter of the callback function will be the array containing information for each observed element.
If you print the entry in the console, you can see the value contained in each element.
The most useful properties from the output are isIntersecting, target and intersectionRect
• isIntersecting: This will be true when the element intersects with the default root which is viewport in our case
• target: This will be the actual element on the page which we will be observing
options object which is a second parameter to Intersection Observer constructor has three properties
• root: The element that is used as the viewport for checking visibility of the target(which is the browser by default if not specified or specified as null)
• threshold: This value ranges from 0 to 1. It is a single number or an array of numbers which indicates at what percentage of the target’s visibility the callback should be executed. If you only want to detect when visibility passes the 50% mark, you can use a value of 0.5. If you want the callback to run every time visibility passes another 25%, you would specify the array [0, 0.25, 0.5, 0.75, 1]. The default value for threshold is 0 (meaning as soon as even one pixel is visible, the callback will be executed). A value of 1 means that the threshold isn’t considered passed until every pixel is visible.
• rootMargin: Specifies the margin around the root. It’s similar to CSS margin property, e.g. “10px 20px 30px 40px” (top, right, bottom, left). The values can be percentages. The default value is 0px. Note, If you specify the value in pixels, you can’t omit the px keyword so “10px 0 30px 40px” is invalid. You have to add the px keyword otherwise it will not work.
Let’s add the options object which is the second parameter to the Intersection Observer constructor.
rootMargin option
Lazy load images on scroll
This is one of the most useful features of the Intersection Observer. If the website has a lot of images displayed, then it will take some time to get those images displayed as the browser downloads the images one by one.
So instead of downloading all the images of the page at once, we can download only the images which are on the display area and download more images as the user scrolls. This will save the bandwidth and will also load the page faster.
To lazy load the images, we need a section that we can observe which will trigger the loading of new images.
Here, we will load the images inside the container div and when the loading div is visible on the viewport, we will call a function to download more images and append it to the container div.
Once we have reached the number of images to load, we will stop loading more images by unobserving the loading div and removing the loading div