Explain the Intersection Observer API in plain language
Yesterday I wrote a blog about lazy loading instructions for custom images in Vue2 . The article data is very good, and the reading volume can be thousands of times. What an honor for me, a new blogger who has just blogged for a week.
So here I would like to thank all the readers and the big family of the Nuggets. It is you who affirmed me and gave me the motivation to learn and write blogs.
Then let’s update today’s article now and continue yesterday’s article. In yesterday’s article, a friend recommended in the comment area Intersection Observer API
to achieve lazy loading of images. In this blog, I will introduce this API first, but the compatibility of this API is average. And it is completely incompatible with IE, so please use it with caution in actual projects.
But before introducing the Intersection Observer API , there are three other knowledge points, namely
the IntersectionObserver() constructor , the IntersectionObserverEntry object and the IntersectionObserverEntry object .
Their previous relationship is more complicated. You can first look at the overall relationship diagram, as well as their parameters, attributes and methods.
1. Basic introduction to Intersection Observer API
Intersection Observer API
Provides a method for asynchronously detecting changes in the intersection of a target element with an ancestor element or viewport (which can be collectively referred to as the root element) .
- Note :
Because this API is asynchronous , it will not be triggered synchronously with the scrolling of the target element,IntersectionObserver API
but be implemented through requestIdleCallback() , that is, the observer will be executed only when the browser is idle. This means that this observer has a very low priority.
1.1 The reason for the Intersection Observer API
Because in the process of web page development today, it is often necessary to determine whether an element has entered the "viewport" (viewport), that is, whether the user can see it.
When facing this kind of intersection detection task, we usually used Element.getBoundingClientRect()
methods such as etc. to obtain the position information of related elements, and also used event monitoring .
However, APIs such as event monitoring and calling are running on the main thread , so frequent triggering and calling will cause performance problems , and this detection method is cumbersome to use .Element.getBoundingClientRect()
Therefore, the official proposed Intersection Observer API
that the emergence of this API is to efficiently solve the following two types of problems:
- Whether an element is visible, such as:
- Image lazy loading - when the image is scrolled to be visible, it will be loaded
- Infinite scrolling of content - when the user scrolls to the bottom, load more directly without turning the page, giving the user the illusion that the webpage can scroll infinitely
- Whether two elements intersect, such as:
- Detect the exposure of the advertisement - in order to calculate the advertising revenue, you need to know the exposure of the advertising elements
- Perform tasks or play animations when the user sees an area
Intersection Observer API
A callback function will be registered, which will only be triggered in the following two situations:
- The target element enters or exits the root element
- When the crossover ratio reaches the threshold , add points:
- However, the API cannot provide the number of overlapping pixels or which pixel overlaps. It can only set the threshold to call the control callback function.
In this way, the main thread of the browser does not need to monitor whether the elements intersect , and IntersectionObserver API
the detection is performed asynchronously, and the resources of the main thread will not be occupied, thereby improving performance.
1.2 Important concepts of Intersection observer
Intersection observer API has the following five important concepts:
- target element — the element we want to listen to
- The root (root) element —the element that helps us determine whether the target element meets the conditions.
In the following two cases, the root element will default to the viewport of the top-level document (usually html).- When the target element is not a descendant of a scrollable element and no value is passed
- Specifies that the root element is null
- Intersection ratio —the representation of the intersection of the target element and the root relative to the percentage of the target element (value range 0.0-1.0).
- threshold — The condition under which the callback function fires.
- callback function (callback) — the function configured for the API, which will be triggered under the set conditions.
2. IntersectionObserver() constructor
**IntersectionObserver()** constructor is used to create an IntersectionObserver object, and will put the object back.
The configuration parameters of the constructor function are shown in the following figure:
Its syntax is as follows:
var observer = new IntersectionObserver(callback[, options]);
2.1 Parameters and return values of the IntersectionObserver() constructor
First of all, let's take a look at IntersectionObserver()
the parameters of the constructor. The parameters are:
-
callback (required parameter) — triggers a callback function when the cross ratio exceeds the specified threshold, this function accepts two parameters:
entries
—IntersectionObserverEntry
An array of objects
but each triggered threshold deviates more or less from the specified threshold.observer
— Returns the calledIntersectionObserver
instance.
-
options (optional parameter) — used to configure the triggering conditions of the callback function, and there are three sub-parameters under the parameter:
root
— Specifies the root element. Used to check the visibility of the target. Defaults to the browser viewport .- If null is specified, also the browser viewport.
- Must be a parent element of the target element.
rootMargin
— The scaling margin of the root element. Its value-passing form is the same as margin in CSS, and is used to control the scaling of each side of the root element (unit is px or %), thereby controlling the range of the area where the intersection of the root element and the target element is calculated. The default value is 0 .threshold
— Threshold, the condition for the callback function to trigger. The value range is 0.0-1.0, and the default value is 0.0 .- When a numeric type is passed in, it will only be triggered once.
- When an array type is passed in, it can be triggered multiple times.
- For example: [0, 0.25, 0.5, 0.75, 1] means that the target element will execute a callback every time the visibility of the target element is increased by 25%.
-
Return value of this function:
a newIntersectionObserver
object.- This object will listen to the target element according to the set threshold.
- Call its own
observe()
method to start monitoring the target element.
2.2 Basic syntax and exception information of the IntersectionObserver() constructor
The syntax for creating an IntersectionObserver object and monitoring it using the IntersectionObserver() constructor is as follows:
let options = {
root: document.querySelector("#root"), //根元素
rootMargin: "0px", //传值形式类似于css的margin 传一个值则四个边都为0
threshold: 0, //触发条件 表示目标元素刚进入根元素时触发
};
//IntersectionObserver对象
let observer = new IntersectionObserver(callback, options);
let target = document.querySelector("#target"); //目标元素
observer.observe(target); //开始监听该目标元素
- Two exception types:
- SyntaxError — The specified rootMargin does not exist or is not syntactical.
- RangeError — One or more threshold values are outside the range 0.0 to 1.0.
3. IntersectionObserver object
The IntersectionObserver interface (subordinate to Intersection Observer API
) provides a way to asynchronously observe the state of the intersection of the target element with the root element .
When the IntersectionObserver object is created, it will be specified the monitored root element, threshold and other information. Once an IntersectionObserver is created its specification cannot be changed.
- So a given observer object can only be used to monitor specific changes in the visible area; of course, you can also configure monitoring multiple target elements in the same observer object.
The properties and methods of this object are shown in the figure below:
3.1 Properties and methods of IntersectionObserver object
3.1.1 Three attributes
The three properties of the object IntersectionObserver()
are similar to the options parameter of the constructor, and these three properties can only be read and cannot be changed.
Attributes | illustrate | Defaults |
---|---|---|
root | Specifies the root element. If null is passed, the viewport of the top-level document. | The viewport of the top-level document (typically html) |
rootMargin | The scaling margin of the root element. Its passed-value form is the same as margin in CSS, and is used to control the scaling of each side of the root element (unit is px or %), thereby controlling the range of the area where the intersection of the root element and the target element is calculated. The unit is px or %. silent | "0px 0px 0px 0px" |
thresholds | An array containing thresholds, in ascending order, where each threshold in the list is the ratio of the listening object's intersection area to the boundary area. The callback function is triggered when any threshold of the listener object is crossed. | 0 |
3.1.2 Four methods
The four methods of this object are as follows:
method | illustrate |
---|---|
observe(target) | Start listening to the specified target element |
unobserve(target) | Stop listening to the specified target element |
takeRecords() | Returns an array of IntersectionObserverEntry objects for all observed targets |
disconnect() | Make the IntersectionObserver object stop all monitoring work |
4. IntersectionObserverEntry object
IntersectionObserverEntry
Interface (pertaining to the Intersection Observer API) describes the intersection state of the target element and its root element container at a specific transition moment.
IntersectionObserverEntry
The object arrayentries
is passed as a parameter IntersectionObserver
to the object callback function; furthermore, this object array can only be IntersectionObserver.takeRecords()
obtained by calling it.
The main properties of this object are shown in the figure below:
4.1 Properties of the IntersectionObserverEntry object
The seven properties of the IntersectionObserverEntry object are all read-only properties , as shown in the following table:
Attributes | illustrate |
---|---|
target | Returns the target element, indicating the element currently being monitored by the object |
isIntersecting | Returns a Boolean value, true when the target element just appears in the visible area of the root element; false when the target element disappears from the visible area of the root element; the above two cases will trigger the callback function |
boundingClientRect | Returns the information of the rectangular area of the target element, the return result is the same as element.getBoundingClientRect() |
rootBounds | Returns the information of the rectangular area of the root element, the return value of the getBoundingClientRect() method, if there is no root element (that is, scrolling directly relative to the viewport), it returns null |
intersectionRect | Returns information about the intersection area between the target element and the viewport (or root element) |
intersectionRatio | Returns the visible ratio of the target element, that is, the ratio of intersectionRect the target boundingClientRect element, which is 1 when it is fully visible, and less than or equal to 0 when it is completely invisible |
time | Returns a IntersectionObserver timestamp from the time origin of the record to the time when the crossover was triggered |
5. Intersection Observer API Compatibility
The compatibility of this API is as follows:
For details, please refer to CAN I USE - intersectionobserver .
6. A simple example of the Intersection Observer API
You can run the following code on your computer, and you will have a deeper understanding.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
}
.container > div {
margin: 5px auto;
width: 100px;
height: 100px;
outline: 1px solid red;
}
</style>
</head>
<body>
<div class="container">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
<div class="item">5</div>
<div class="item">6</div>
<div class="item">7</div>
<div class="item">8</div>
<div class="item">9</div>
<div class="item">10</div>
<div class="item">11</div>
<div class="item">12</div>
<div class="item">13</div>
<div class="item">14</div>
<div class="item">15</div>
</div>
<script>
//io 为 IntersectionObserver对象 - 由IntersectionObserver()构造器创建
var io = new IntersectionObserver((entries) => {
//entries 为 IntersectionObserverEntry对像数组
entries.forEach((item) => {
//item 为 IntersectionObserverEntry对像
// isIntersecting是一个Boolean值,判断目标元素当前是否可见
if (item.isIntersecting) {
//div 可见时 进行相关操作
console.log(item.target.innerText);
io.unobserve(item.target); //停止监听该div DOM节点
}
});
}); //不传options参数,默认根元素为浏览器视口
const divArr = [...document.querySelectorAll(".item")];
divArr.forEach((div) => io.observe(div)); // 遍历监听所有div DOM节点
</script>
</body>
</html>
Intersection Observer API
I have implemented the image lazy loading effect in Vue2 , you can go and have a look. Lazy loading instructions for custom images in Vue2 2.0
reference blog
- MDN - Intersection Observer API
- MDN - IntersectionObserver.IntersectionObserver()
- MDN - Intersection Observer
- MDN - IntersectionObserverEntry
- Super easy-to-use API IntersectionObserver
- Ruan Yifeng - IntersectionObserver API Tutorial
epilogue
This is the best answer in the knowledge I know so far, and of course there may be some misunderstandings.
So if you have doubts about this article, you can leave a message in the comment area, and I will reply in time. You are welcome to point out the wrong views in the article.
In the end, the code words are not easy, and friends who find it helpful will like, bookmark, and follow along.