Intersection Observer API

Spread the love

The Intersection Observer API allows us to asynchronously check whether an element is visible or to observe changes in the intersection of a target element with an ancestor element.

Creating an Observer

To use the API, we first need to create an observer, the observer is created using the constructor taking in 2 parameters

var observer = new IntersectionObserver( callback, options);

Callback is the function that is called when there is a change in the target intersection, the options parameter is an optional object specifying various options. The options available are

root

This option specifies the element that is used as the viewport for checking visiblity of the target. It must be the ancestor of the target. Default – browser viewport. 

rootMargin

Margin around the root. Its value can be in pixels or percentages. It is to grow or shrink each side of the root element’s bounding box before computing intersections.

Default – 0

threshold

It specifies when the callback should be triggered. It is a float value from 0 to 1 which specifies how much of the target element must be visible before calling the callback function.

Default – 0

Example: A value of 0.5 specifies that half the target element must intersect with the root element before the callback function is called, A value of 1 specifies that 100% of the target element must intersect before the callback function is called.

 Start Observing

Once you create an observer, you need to target an element to be observed, you do this using the observe method of the observer object passing in the target element

var target = document.getElementById('#target');
observer.observe(target);

The above code starts observing the element with id “target”, now whenever the element intersects, the callback function is called.

Stop Observing

You can stop observing on a particular element by calling the unobserve method

// stop observing
io.unobserve(target);

Close Observer

You can also close the observer object by calling its disconnect method

// close observer
io.disconnect();

Callback function

The callback function is called every time you target element intersects with your root element and also when the target element goes out of the root element.

The callback function get an array of objects, each object in the array corresponds to a single target element whose intersection has changed. The object has the following properties.

boundingClientRect

The positions and dimensions of the target element.

intersectionRatio

The percentage of the target element that is intersecting with the root element.

intersectionRect

The position and dimension of the rectangle representing the portion where the target and root elements intersect.

isIntersecting

Whether the target element is intersecting with the root element or not

rootBounds

The positions and dimensions of the root element

target

The target DOM element

time

Time of the intersection event in milliseconds.

Browser Support

A few browsers do not support the Intersection Observer API, you can find the list of browsers supported here. You can use this polyfill  for unsupported browsers.

Demo – Lazy Load Images

Now that the theory of the API is done with, below is a simple demo to illustrate how to use the API. This demo comprises less than 20 lines of JavaScript(ignoring comments) to lazy load images when they become visible.

The code for this demo is available on github here.

First lets start with a blank html page, then in the html page add image tags without any source like so

<img class="lazy-load" lazy-load-url="some_url">

Each image has a class lazy-load so that we know which image should be lazy loaded, each image also has the lazy-load-url attribute which specifies the url of the image that must be loaded when the image comes into view.

Next we add some css so that all the empty images occupy some space so that they are all not in view at the same time

.lazy-load{
width: 100%;
display: block;
margin: auto;
min-width: 100%;
min-height: 80%;
object-fit: cover;
}
html, body{
height: 100%;
}

Next we add the JavaScript to lazy load the images, we first get the array of images to be lazy loaded

var img_arr = document.querySelectorAll('img.lazy-load');

Next we create an intersection API observer

const observer = new IntersectionObserver(loadImg);

We pass in the loadImg function which will be called when the intersection of the images change.

Next we observe each image in the array

img_arr.forEach(function (element) {
observer.observe(element);
})

Now that all the images are being observed, we now have to implement the loadImg function, the function gets the array of intersection objects , then checks if the image is visible, if it is it then loads the src of the image and then unobserves the image element

function loadImg(array) {

// for each object in the intersection array
array.forEach(obj=>{

// if the object is visible
if(obj.isIntersecting){

// the target element
var target = obj.target;

// the src url of the image
var src = target.getAttribute("lazy-load-src");

// update the src of the image (loads the image)
target.src = src;

// unobserve the image since it is now loaded
observer.unobserve(target);
}

})

}