Back to Blog Page
Frontend Development

How to Use The JavaScript Intersection Observer API

How to Use The JavaScript Intersection Observer API

Written by Kolade Chris | Sep 21, 2024 | #JavaScript | 5 minutes Read

In simple terms, the JavaScript intersection observer API is a tool that lets you know when an element on a webpage is visible on the screen.

The API makes it easy to detect when elements enter or leave the viewport, removing the need for complex scroll event handling. This allows developers to execute actions based on the visibility of elements within the viewport.

The said actions include lazy-loading images, implementing infinite scrolling, or triggering animations when elements become visible.

Keep reading as I walk you through the syntax of the Intersection Observer API and share three examples to help you start using it in your projects.

Basic Syntax of the Intersection Observer API

Below is the basic syntax of the intersection observer API:

1
const observerVariable = new IntersectionObserver(
2
callbackFunc,
3
observerOptions
4
);
5
6
observerVariable.observe(targetElement);

Let’s look at each of the items in the syntax:

  • InterSectionObserver() is the API itself. It’s a constructor, so you need to initialize it with the new keyword. It takes two parameters – a callback function and an optional options object.
  • callbackFunc is the callback function is the function that will be called whenever the observed element enters or exits the viewport
  • observerOptions is an object that allows you to specify the root element for observing, margins around the root, and visibility thresholds to trigger the callback.
  • observerVariable is the constant you have to assign the instance of the IntersectionObserver constructor to. It’s an identifier (a name), so you can call it whatever you want.
  • observerVariable.observe(targetElement) is the line that will finally do the slam dunk with the observe() method. The targetElement is the element you want to do something with.

Let’s look at 3 examples of the ways you can use the intersection observer API:

  • the first example will focus on observing a single element and using the basic syntax as is
  • the second will observe one element too but make the syntax clearer
  • the third will show you how to observe multiple elements without defining separate observers for them

Example 1: Using the Intersection Observer API to Observe a Single Element

Let’s observe the h1 element in the HTML code below:

1
<!doctype html>
2
<html lang="en">
3
<head>
4
<meta charset="UTF-8" />
5
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
<title>JS Intersection Observer API</title>
7
<link rel="stylesheet" href="styles.css" />
8
</head>
9
<body>
10
<h1 class="heading">JavaScript Intersection Observer API</h1>
11
150 collapsed lines
12
<p>
13
Lorem, ipsum dolor sit amet consectetur adipisicing elit. Dolore nihil
14
veniam ipsa numquam totam eligendi eaque error eum, voluptates enim
15
laudantium sapiente, hic unde inventore a dolorem adipisci consequuntur
16
assumenda tempora nobis iste voluptate officiis nesciunt. Neque numquam
17
iusto ipsum quos tempora delectus expedita autem eaque facere voluptate
18
rerum ab possimus, explicabo quasi! Culpa asperiores temporibus dicta
19
error est, consectetur exercitationem nihil optio voluptate pariatur.
20
Voluptatem provident autem, officiis qui quod porro facilis libero
21
molestias error dolorum, ad nihil suscipit recusandae, aliquid animi. A,
22
temporibus? Optio fugit sed natus recusandae fugiat veniam illo hic
23
aperiam officia inventore ea molestiae itaque qui, deleniti officiis?
24
Aliquid fuga nisi veritatis commodi doloribus sit rerum alias adipisci
25
natus. Incidunt totam reprehenderit atque deserunt veritatis iste
26
perferendis tempora minima, commodi asperiores quae recusandae aliquam
27
error quisquam ab eveniet quam provident, possimus natus, necessitatibus
28
unde ratione.
29
</p>
30
<p>
31
Lorem, ipsum dolor sit amet consectetur adipisicing elit. Dolore nihil
32
veniam ipsa numquam totam eligendi eaque error eum, voluptates enim
33
laudantium sapiente, hic unde inventore a dolorem adipisci consequuntur
34
assumenda tempora nobis iste voluptate officiis nesciunt. Neque numquam
35
iusto ipsum quos tempora delectus expedita autem eaque facere voluptate
36
rerum ab possimus, explicabo quasi! Culpa asperiores temporibus dicta
37
error est, consectetur exercitationem nihil optio voluptate pariatur.
38
Voluptatem provident autem, officiis qui quod porro facilis libero
39
molestias error dolorum, ad nihil suscipit recusandae, aliquid animi. A,
40
temporibus? Optio fugit sed natus recusandae fugiat veniam illo hic
41
aperiam officia inventore ea molestiae itaque qui, deleniti officiis?
42
Aliquid fuga nisi veritatis commodi doloribus sit rerum alias adipisci
43
natus. Incidunt totam reprehenderit atque deserunt veritatis iste
44
perferendis tempora minima, commodi asperiores quae recusandae aliquam
45
error quisquam ab eveniet quam provident, possimus natus, necessitatibus
46
unde ratione.
47
</p>
48
<p>
49
Lorem, ipsum dolor sit amet consectetur adipisicing elit. Dolore nihil
50
veniam ipsa numquam totam eligendi eaque error eum, voluptates enim
51
laudantium sapiente, hic unde inventore a dolorem adipisci consequuntur
52
assumenda tempora nobis iste voluptate officiis nesciunt. Neque numquam
53
iusto ipsum quos tempora delectus expedita autem eaque facere voluptate
54
rerum ab possimus, explicabo quasi! Culpa asperiores temporibus dicta
55
error est, consectetur exercitationem nihil optio voluptate pariatur.
56
Voluptatem provident autem, officiis qui quod porro facilis libero
57
molestias error dolorum, ad nihil suscipit recusandae, aliquid animi. A,
58
temporibus? Optio fugit sed natus recusandae fugiat veniam illo hic
59
aperiam officia inventore ea molestiae itaque qui, deleniti officiis?
60
Aliquid fuga nisi veritatis commodi doloribus sit rerum alias adipisci
61
natus. Incidunt totam reprehenderit atque deserunt veritatis iste
62
perferendis tempora minima, commodi asperiores quae recusandae aliquam
63
error quisquam ab eveniet quam provident, possimus natus, necessitatibus
64
unde ratione.
65
</p>
66
<p>
67
Lorem, ipsum dolor sit amet consectetur adipisicing elit. Dolore nihil
68
veniam ipsa numquam totam eligendi eaque error eum, voluptates enim
69
laudantium sapiente, hic unde inventore a dolorem adipisci consequuntur
70
assumenda tempora nobis iste voluptate officiis nesciunt. Neque numquam
71
iusto ipsum quos tempora delectus expedita autem eaque facere voluptate
72
rerum ab possimus, explicabo quasi! Culpa asperiores temporibus dicta
73
error est, consectetur exercitationem nihil optio voluptate pariatur.
74
Voluptatem provident autem, officiis qui quod porro facilis libero
75
molestias error dolorum, ad nihil suscipit recusandae, aliquid animi. A,
76
temporibus? Optio fugit sed natus recusandae fugiat veniam illo hic
77
aperiam officia inventore ea molestiae itaque qui, deleniti officiis?
78
Aliquid fuga nisi veritatis commodi doloribus sit rerum alias adipisci
79
natus. Incidunt totam reprehenderit atque deserunt veritatis iste
80
perferendis tempora minima, commodi asperiores quae recusandae aliquam
81
error quisquam ab eveniet quam provident, possimus natus, necessitatibus
82
unde ratione.
83
</p>
84
<p>
85
Lorem, ipsum dolor sit amet consectetur adipisicing elit. Dolore nihil
86
veniam ipsa numquam totam eligendi eaque error eum, voluptates enim
87
laudantium sapiente, hic unde inventore a dolorem adipisci consequuntur
88
assumenda tempora nobis iste voluptate officiis nesciunt. Neque numquam
89
iusto ipsum quos tempora delectus expedita autem eaque facere voluptate
90
rerum ab possimus, explicabo quasi! Culpa asperiores temporibus dicta
91
error est, consectetur exercitationem nihil optio voluptate pariatur.
92
Voluptatem provident autem, officiis qui quod porro facilis libero
93
molestias error dolorum, ad nihil suscipit recusandae, aliquid animi. A,
94
temporibus? Optio fugit sed natus recusandae fugiat veniam illo hic
95
aperiam officia inventore ea molestiae itaque qui, deleniti officiis?
96
Aliquid fuga nisi veritatis commodi doloribus sit rerum alias adipisci
97
natus. Incidunt totam reprehenderit atque deserunt veritatis iste
98
perferendis tempora minima, commodi asperiores quae recusandae aliquam
99
error quisquam ab eveniet quam provident, possimus natus, necessitatibus
100
unde ratione.
101
</p>
102
103
<div class="box"></div>
104
105
<p>
106
Lorem, ipsum dolor sit amet consectetur adipisicing elit. Dolore nihil
107
veniam ipsa numquam totam eligendi eaque error eum, voluptates enim
108
laudantium sapiente, hic unde inventore a dolorem adipisci consequuntur
109
assumenda tempora nobis iste voluptate officiis nesciunt. Neque numquam
110
iusto ipsum quos tempora delectus expedita autem eaque facere voluptate
111
rerum ab possimus, explicabo quasi! Culpa asperiores temporibus dicta
112
error est, consectetur exercitationem nihil optio voluptate pariatur.
113
Voluptatem provident autem, officiis qui quod porro facilis libero
114
molestias error dolorum, ad nihil suscipit recusandae, aliquid animi. A,
115
temporibus? Optio fugit sed natus recusandae fugiat veniam illo hic
116
aperiam officia inventore ea molestiae itaque qui, deleniti officiis?
117
Aliquid fuga nisi veritatis commodi doloribus sit rerum alias adipisci
118
natus. Incidunt totam reprehenderit atque deserunt veritatis iste
119
perferendis tempora minima, commodi asperiores quae recusandae aliquam
120
error quisquam ab eveniet quam provident, possimus natus, necessitatibus
121
unde ratione.
122
</p>
123
124
<p>
125
Lorem, ipsum dolor sit amet consectetur adipisicing elit. Dolore nihil
126
veniam ipsa numquam totam eligendi eaque error eum, voluptates enim
127
laudantium sapiente, hic unde inventore a dolorem adipisci consequuntur
128
assumenda tempora nobis iste voluptate officiis nesciunt. Neque numquam
129
iusto ipsum quos tempora delectus expedita autem eaque facere voluptate
130
rerum ab possimus, explicabo quasi! Culpa asperiores temporibus dicta
131
error est, consectetur exercitationem nihil optio voluptate pariatur.
132
Voluptatem provident autem, officiis qui quod porro facilis libero
133
molestias error dolorum, ad nihil suscipit recusandae, aliquid animi. A,
134
temporibus? Optio fugit sed natus recusandae fugiat veniam illo hic
135
aperiam officia inventore ea molestiae itaque qui, deleniti officiis?
136
Aliquid fuga nisi veritatis commodi doloribus sit rerum alias adipisci
137
natus. Incidunt totam reprehenderit atque deserunt veritatis iste
138
perferendis tempora minima, commodi asperiores quae recusandae aliquam
139
error quisquam ab eveniet quam provident, possimus natus, necessitatibus
140
unde ratione.
141
</p>
142
143
<p>
144
Lorem, ipsum dolor sit amet consectetur adipisicing elit. Dolore nihil
145
veniam ipsa numquam totam eligendi eaque error eum, voluptates enim
146
laudantium sapiente, hic unde inventore a dolorem adipisci consequuntur
147
assumenda tempora nobis iste voluptate officiis nesciunt. Neque numquam
148
iusto ipsum quos tempora delectus expedita autem eaque facere voluptate
149
rerum ab possimus, explicabo quasi! Culpa asperiores temporibus dicta
150
error est, consectetur exercitationem nihil optio voluptate pariatur.
151
Voluptatem provident autem, officiis qui quod porro facilis libero
152
molestias error dolorum, ad nihil suscipit recusandae, aliquid animi. A,
153
temporibus? Optio fugit sed natus recusandae fugiat veniam illo hic
154
aperiam officia inventore ea molestiae itaque qui, deleniti officiis?
155
Aliquid fuga nisi veritatis commodi doloribus sit rerum alias adipisci
156
natus. Incidunt totam reprehenderit atque deserunt veritatis iste
157
perferendis tempora minima, commodi asperiores quae recusandae aliquam
158
error quisquam ab eveniet quam provident, possimus natus, necessitatibus
159
unde ratione.
160
</p>
161
162
<p>
163
Lorem, ipsum dolor sit amet consectetur adipisicing elit. Dolore nihil
164
veniam ipsa numquam totam eligendi eaque error eum, voluptates enim
165
laudantium sapiente, hic unde inventore a dolorem adipisci consequuntur
166
assumenda tempora nobis iste voluptate officiis nesciunt. Neque numquam
167
iusto ipsum quos tempora delectus expedita autem eaque facere voluptate
168
rerum ab possimus, explicabo quasi! Culpa asperiores temporibus dicta
169
error est, consectetur exercitationem nihil optio voluptate pariatur.
170
Voluptatem provident autem, officiis qui quod porro facilis libero
171
molestias error dolorum, ad nihil suscipit recusandae, aliquid animi. A,
172
temporibus? Optio fugit sed natus recusandae fugiat veniam illo hic
173
aperiam officia inventore ea molestiae itaque qui, deleniti officiis?
174
Aliquid fuga nisi veritatis commodi doloribus sit rerum alias adipisci
175
natus. Incidunt totam reprehenderit atque deserunt veritatis iste
176
perferendis tempora minima, commodi asperiores quae recusandae aliquam
177
error quisquam ab eveniet quam provident, possimus natus, necessitatibus
178
unde ratione.
179
</p>
180
181
<div class="circle"></div>
182
183
<script src="script.js"></script>
184
</body>
185
</html>

Here’s the CSS for the HTML:

1
* {
2
margin: 0;
3
padding: 0;
4
box-sizing: border-box;
5
}
6
7
body {
8
max-width: 1000px;
9
margin: 0 auto;
10
transition: 2s ease-in-out;
11
}
12
13
h1 {
14
margin: 1rem 0;
15
}
26 collapsed lines
16
17
p {
18
margin: 4rem 0;
19
line-height: 1.5;
20
}
21
22
@keyframes rotate {
23
from {
24
transform: rotate(0deg);
25
}
26
to {
27
transform: rotate(360deg);
28
}
29
}
30
31
.animate {
32
animation: rotate 2s linear infinite;
33
}
34
35
.box {
36
height: 400px;
37
width: 400px;
38
background-color: #2ecc71;
39
transition: background-color 0.3s;
40
}
41
42
.circle {
43
height: 400px;
44
width: 400px;
45
background-color: #2ecc71;
46
border-radius: 49%;
47
}

To start observing the h1 element, you need to reference it with querySelector [or your favourite method of doing so].

I’ll do that by targeting the .heading class of the h1:

1
const h1 = document.querySelector('.heading');

The next thing to do is to create a new instance of the intersection observer API and pass in the callback and the options.

I’ll start by defining an observerh1 variable set to a new instance of IntersectionObserver(). I will also start observing the h1 element straight away:

1
const observeh1 = new IntersectionObserver();
2
3
observeh1.observe(h1);

For the callback, I’m going to start with an entries parameter for an arrow function, I’ll also log the entries parameter to the console:

1
const observeh1 = new IntersectionObserver((entries) => {
2
console.log(entries);
3
});

h1 observed in the console

You can see that the target is indeed the h1 element with the class heading.

There’s also an isIntersecting property you can use to check if the target element is in the viewport.

Let’s loop through the entries (only h1 for now, actually) and do something using the isIntersecting property based on whether the h1 is in the viewport or not:

1
const observeh1 = new IntersectionObserver((entries) => {
2
entries.forEach((entry) => {
3
if (entry.isIntersecting) {
4
console.log('h1 is in the viewport!');
5
} else {
6
console.log('h1 is out of the viewport!');
7
}
8
});
9
});
10
11
observeh1.observe(h1);

Here’s the result:

h1 observed without styling

Isn’t that what we all call “cool”?

You can take things further and assign some style to the target element once it’s in the viewport:

1
const observeh1 = new IntersectionObserver((entries) => {
2
entries.forEach((entry) => {
3
if (entry.isIntersecting) {
4
console.log('h1 is in the viewport!');
5
entry.target.style.backgroundColor = '#3498db';
6
entry.target.style.fontSize = '4rem';
7
} else {
8
console.log('h1 is out of the viewport!');
9
entry.target.style.backgroundColor = 'unset';
10
entry.target.style.fontSize = 'unset';
11
}
12
});
13
});

For the optional options object, I’ll pass in the following:

1
const observeh1 = new IntersectionObserver(
2
(entries) => {
3
entries.forEach((entry) => {
4
if (entry.isIntersecting) {
5
console.log('h1 is in the viewport!');
6
entry.target.style.backgroundColor = '#3498db';
7
entry.target.style.fontSize = '4rem';
8
} else {
9
console.log('h1 is out of the viewport!');
10
entry.target.style.backgroundColor = '#2ecc71';
11
entry.target.style.fontSize = 'unset';
12
}
13
});
14
},
15
{
16
root: null,
17
rootMargin: '200px',
18
threshold: 0.5,
19
}
20
);
21
22
observeh1.observe(h1);

Don’t be confused. Here’s what those mean:

  • a root of null means the observer will use the entire browser viewport as the area to watch for visibility changes
  • a rootMargin of 200px means the observer will add an extra 200px around the root area (the entire browser viewport for this example) , so elements will be considered visible even when they are still 200 pixels outside the root
  • a threshold of 0.5 means 50% of the element needs to be visible before the observer callback will be triggered

This is what things look like now:

h1 observed with styling

In case you’re doubting it, things really do change if you inspect the h1 element:

Confirm h1 intersection

Example 2: Defining the Callback and Options Outside of the IntersectionObserver Constructor

You don’t have to fill up the IntersectionObserver constructor with the callback function and options parameters. You can define both outside and reference them inside the constructor.

To show you how to do this, let’s observe the box inside the HTML code. Here’s the fully commented code that shows you what’s going on:

1
const box = document.querySelector('.box');
2
3
// Define the callback function outside the constructor
4
const observerCallback = (entries) => {
5
entries.forEach((entry) => {
6
if (entry.isIntersecting) {
7
// Once the box is within the viewport:
8
9
// 1. Log "Box is in the viewport!" to the console
10
console.log('Box is in the viewport!');
11
// 2. Change the background color to blue
12
entry.target.style.backgroundColor = '#3498db';
13
// 3. Add a class that animates the box
14
entry.target.classList.add('animate');
15
} else {
16
// Once the box is outside the viewport:
17
18
// 1. Log "Box is out of the viewport!" to the console
19
console.log('Box is out of the viewport!');
20
// 2. Change the background color to green
21
entry.target.style.backgroundColor = '#2ecc71';
22
// 3. Remove the class that animates the box
23
entry.target.classList.remove('animate');
24
}
25
});
26
};
27
28
// Define the options
29
const observerOptions = {
30
root: null,
31
rootMargin: '0px',
32
threshold: 0.5,
33
};
34
35
// Define the constructor and reference the callback function and the options
36
const observer = new IntersectionObserver(observerCallback, observerOptions);
37
38
// Observe the box
39
observer.observe(box);

Here’s what’s happening to the box now:

Box intersecting

Pardon the interruption

Subscribe to my newsletter for coding tips, videos from reputable sources, articles from OG tech authors, and a ton of other goodies.

No BS. No fluff. Just pure software development goodies on a Sunday every week.

Back to the intersection observer API

Example 3: How to Observe Multiple Elements with the IntersectionObserver API

Observing multiple element with the IntersectionObserver API works a bit differently.

To do that, you need to do these:

  • select your elements from the HTML with querySelectorAll() or other relevant methods
  • define your callback and options as usual
  • supply the callback and the options parameters into the IntersectionObserver API constructor
  • loop through the target elements with forEach and observe them inside it

Here’s how I was able to observe the circle and box on the page:

1
// select the target box and the circle with querySelectorAll()
2
const targets = document.querySelectorAll('.box, .circle');
3
4
//define the callback function
5
const observerCallback = (entries) => {
6
entries.forEach((entry) => {
7
// Once the targets are within the viewport:
8
if (entry.isIntersecting) {
9
// 1. Log "[target] is in the viewport" to the console
10
console.log(`${entry.target.className} is in the viewport!`);
11
// 2. Add a blue background color to the targets
12
entry.target.style.backgroundColor = '#3498db';
13
// 3. Animate the target
14
entry.target.classList.add('animate');
15
} else {
16
// Once the targets are out of the viewport:
17
18
// 1. Log "[target] is out of the viewport" to the console
19
console.log(`${entry.target.className} is out of the viewport!`);
20
// 2. Add a green background color to the targets
21
entry.target.style.backgroundColor = '#2ecc71';
22
// 3. Remove the animation from the target
23
entry.target.classList.remove('animate');
24
}
25
});
26
};
27
28
// define the options
29
const observerOptions = {
30
root: null,
31
rootMargin: '0px',
32
threshold: 0.5,
33
};
34
35
// pass the callback and options into the constructor
36
const observer = new IntersectionObserver(observerCallback, observerOptions);
37
38
// loop through the selected targets and observe them
39
targets.forEach((target) => observer.observe(target));

Here are the box and the circle intersecting:

Box and circle intersecting

You can see that in the second and third examples, the animation is only triggered once the user scrolls to them. This can be useful when you’re dealing with expensive animations or other processes.

The Intersection Observer API improves user experience by ensuring elements load and animate only when needed, reducing unnecessary processing and enhancing performance. It’s an excellent tool for creating responsive, efficient, and engaging web interactions.

Start using the IntersectionObserver API in your projects now!