Open In App

Introduction to Intersection Observer

Last Updated : 22 Apr, 2024
Improve
Improve
Like Article
Like
Save
Share
Report

Intersection Observer is an API that is used to detect the interaction of a target element with its’s ancestor element or the document viewport. For example, if we want to detect if some element is visible in the viewport we can use this API for that purpose.

Some of the use cases of Intersection Observer are:

  • Lazy loading images.
  • Detect if an element is in the viewport or not.
  • Auto-play a video if in the viewport, otherwise pause the video.
  • Infinite scrolling.

How to use Intersection Observer?

Intersection Observer API can be used to observe an element. This API takes two inputs:

  • A Callback function: This function receives a list of entries (elements) that are to be observed by an ancestor or document viewport. This list of entries has the property isIntersecting which can be used to determine if the target entry is visible or not. If this property returns true then it means the target is visible else it’s not.
  • An object with properties root, threshold, and rootMargin.
    • root property is used to tell the element that is used as the viewport for checking the visibility of the target element and it must be the ancestor of the target element, and if not specified then document viewport is the default value.
    • threshold property can be a number or an array of numbers. It is used to tell how much of the target element should be visible when the above callback function gets triggered. For example, if the threshold is 0.5, then the callback function will be triggered when half of the target element is visible in the viewport and if the threshold is [0.5,0.25] then when the target element’s half and one-fourth part is visible then the callback function will be triggered. The default is 0 which means as soon as the target element is visible the callback function will be triggered.
    • rootMargin property is the same as the CSS’s margin property which can take either one value(applicable to all four margins) or multiple values for the individual margins. This property can be used to grow or shrink the container viewport. For example, if rootMargin is 20px the viewport will be 20px larger so once the target element is 20px from being within the viewport it will be considered intersecting. The default value is 0 for the margins.

This API returns an object which has a property observe which can be used to observe our desired target element.

Let’s see an example to understand how this API really works.

Problem Statement: We will have a div element(this will be our target element) and some para elements inside a scrollable div container. We will have another button which when clicked will display an alert box that will tell if the target element is visible in the container div or not.

Approach:

1. we will create a div with the class container, and add some para elements and another div with a class target inside the container div. The container div will act as our root element. Also, we will create a button that will be clicked to display the alert box and we will declare a variable isVisible which will be used to store information whether the target is visible or not.

const container = document.querySelector(".container");
const target = document.querySelector(".target");
const btn = document.querySelector(".btn");
let isVisible = null;

2. We will set the container div as our root and threshold to 1 which means that whenever the target div is fully visible inside the container div then the isIntersecting property will be true.

const options={
root: container,
threshold: 1
}

3. We will create a callback function, this function will set the value of isVisible. Since there is only one element that will be observed hence we will access entries[0].

const callBack = (entries) => {
isVisible = entries[0].isIntersecting;
};

4. Now we will use Intersection Observer API and pass the above callback function and the options object as input

const observer = new IntersectionObserver(callBack,options);

5. The object returned by the API will be used to observe the button element.

observer.observe(target)

6. We will now attach a click event listener to the button when this button will be clicked it will display an alert box with the message Target Element is visible or Target Element is not visible depending on whether the target is visible or not.

btn.addEventListener("click", () => {
if (isVisible) {
alert("Target Element is visible");
}else {
alert("Target Element is not visible");
}
});
HTML
<!DOCTYPE html>
<html>
<head>
    <title>Intersection Observer</title>
    <meta charset="UTF-8" />
    <link rel="stylesheet" href="./src/styles.css" />
</head>

<body>
    <div>
        <div class="container">
            <div class="content">
                <p>GeeksforGeeks</p>
                <p>GeeksforGeeks</p>
                <p>GeeksforGeeks</p>
                <p>GeeksforGeeks</p>
                <p>GeeksforGeeks</p>
                <p>GeeksforGeeks</p>
                <p>GeeksforGeeks</p>
                <p>GeeksforGeeks</p>
                <p>GeeksforGeeks</p>
                <p>GeeksforGeeks</p>
                <div class="target"></div>
                <p>GeeksforGeeks</p>
                <p>GeeksforGeeks</p>
                <p>GeeksforGeeks</p>
                <p>GeeksforGeeks</p>
                <p>GeeksforGeeks</p>
                <p>GeeksforGeeks</p>
                <p>GeeksforGeeks</p>
                <p>GeeksforGeeks</p>
                <p>GeeksforGeeks</p>
                <p>GeeksforGeeks</p>
            </div>
        </div>
        <button class="btn">
              Check If Target Is Visible
          </button>
    </div>
    <script src="src/index.js"></script>
</body>
</html>
CSS
body {
    font-family: sans-serif;
      display: flex;
      justify-content: center;
}

.container {
    height: 300px;
    width: 200px;
    background-color: ghostwhite;
    border: 1px solid black;
    overflow-y: scroll;
    display: flex;
    flex-direction: column;
}

.content {
    color: green;
    text-align: center;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
}

.target-btn {
    padding: 8px;
    font-size: 20px;
    cursor: pointer;
    color: green;
}

.target {
    height: 100px;
    width: 100px;
    background-color: green;
}

.btn {
    margin-top: 20px;
    padding: 20px;
    cursor: pointer;
}
Javascript
const target = document.querySelector(".target");
const container = document.querySelector(".container");
const btn = document.querySelector(".btn");
let isVisible = null;

const callBack = (entries) => {
      isVisible = entries[0].isIntersecting;
};

const options = {
      root: container,
      threshold: 1
};

const observer = new IntersectionObserver(callBack, options);

observer.observe(target);

btn.addEventListener("click", () => {
      if (isVisible) {
        alert("Target Element is visible");
  } else {
        alert("Target Element is not visible");
  }
});

Output:

Introduction to Intersection Observer

Introduction to Intersection Observer

Explanation: Whenever we click on the button it tells us if the target element is inside the container div or not, but only when it is fully visible since we had set the threshold to 1.



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads