Intersection Observer API

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

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



Default — 0


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

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

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

Stop Observing

// stop observing

Close Observer

// close observer

Callback function

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.









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

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) {



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

// if the object is visible

// the target element
var 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





Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store