Original: www.hweaver.com/intersectio…
It’s no secret that modern websites rely heavily on Scroll events. Scrolling can trigger lazy loading of images or delayed requests for data, initialize animations, support loading of endless content, and much more. The bad thing is that these Scroll events are not very reliable and are resource hogs. This causes problems in terms of implementation and often overloads the browser.
As a new way to handle Scroll events, the Intersection Observer API was born. The API allows the user to observe A specified element A and monitor the state of its intersection with A specific element B (or browser viewport).
What exactly is wrong with the existing implementation? Consider a typical site page today, and there are many Scroll events happening — AD modules, new content that scrolls in from the bottom, elements that need to be animated from time to time, or many images on the page, all scroll until the user sees them before loading or executing them. The scroll event associated with the numerous circulation method is called, there is no lack of among them such as the need to get the position information necessary Element. GetBoundingClientRect (), etc., are sensitive to performance.
These methods all run on the main thread, which means that a problem in one place can affect everything else. The Intersection Observer API frees the browser from dealing with Intersection events by using callbacks that associate the Intersection states of a particular element instead. Browsers can manage these events more efficiently, and performance is optimized.
Note browser compatibility, as of the time of translation:
Concepts & Basic usage
To fully understand why the Intersection Observer API is better for performance, take a look at the basics.
IntersectionObserver definition
There are some key terms used to define an instance of Intersection Observer.
Root refers to an element that waits for an object to intersect with it. By default, this is a browser viewport, but any legal element can be used.
In addition to using root as the basis for a single IntersectionObserver, the observer can also monitor many different targets. The target can also be any legal element, and when any of the targets and the root element intersect, the observer fires a callback.
Basic usage
Establishing a simple IntersectionObserver is very convenient. The IntersectionObserver constructor is first called and passed a callback function and a default option:
const options = {
root: document.querySelector('#viewport'),
rootMargin: '0px'.threshold: 1.0
};
const observer = new IntersectionObserver(callback, options);
Copy the code
As shown above, there are some attributes available in the options:
root
The root element used to check whether it intersects with the target element. This option accepts any legal element, but it is important that the root element be the ancestor of the target element. If the root element is not specified or is set to NULL, the browser viewport is the default root element.
rootMargin
This property is used to expand or reduce the size of the root element. Accept values in the same format as margins in CSS, such as a single value 10px or multiple values defining different edges 10px 11%-10px 25px.
threshold
Finally, the threshold option specifies a minimum that the target element itself must meet before a callback is triggered if the target element and the root element intersect. The value is a floating point number between 0.0 and 1.0, so the intersection rate of about 75% should be written as 0.75. If you want to trigger callbacks at multiple points, you can also pass in an array of values, such as [0.33, 0.66, 1.0].
Once an instance of IntersectionObserver is created, all that remains is to provide one or more target elements for observation: IntersectionObserver
const target = document.querySelector('#target');
observer.observe(target);
Copy the code
Since then, the callback function will be fired when the target (or multiple targets) approaches the intersection threshold.
const callback = function(entries, observer) {
entries.forEach((entry) = > {
// What are you doing here
});
}
Copy the code
Calculation of intersection
It is important to understand how the intersection is calculated. First, the Intersection Observer API treats any object as a rectangle for calculation. These rectangles will be calculated as small as possible, as long as they contain the target content.
For the root element, consider its rectangular boundary based on the rootMargin value, which fills in or reduces the size of the root element.
Finally, it is important to understand that, unlike traditional Scroll events, Intersection Observer does not poll continuously after each Intersection change. In contrast, callbacks are invoked only when the threshold is approximately reached. If multiple checks are required, provide multiple thresholds.
Demo 1 – Animation
In this first small project, we look at the Intersection Observer API in a simple way.
// Animation callback function
const scrollImations = (entries, observer) = > {
entries.forEach((entry) = > {
console.log(111, entry.isIntersecting, entry.intersectionRatio);
if(entry.isIntersecting && entry.intersectionRatio >= 1) {
// See the element completely
entry.target.classList.add('box--visible');
} else {
entry.target.classList.remove('box--visible'); }}); }// Create an observer
const options = {
threshold: 1.0};const observer = new IntersectionObserver(scrollImations, options);
// Specify the target to observe
const boxes = document.querySelectorAll('.box');
boxes.forEach((box) = > {
observer.observe(box);
});
Copy the code
Scroll down and a series of elements appear. One IntersectionObserver instance was used to monitor the three target elements. When they are fully in the viewport (root), append a style class name to the target element, triggering the corresponding CSS animation.
Demo 2 – In-page navigation
The Intersection Observer is useful for navigation bars that are highlighted as they scroll through a single page, corresponding to an area.
// Initialize the observer
const options = {
threshold: 0.45
}
const observer = new IntersectionObserver(changeNav, options);
// Specify the target element
const sections = document.querySelectorAll('section');
sections.forEach((section) = > {
observer.observe(section);
});
Copy the code
The changeNav() callback simply checks if enough target section elements appear on the screen, and then specifies the style class name appropriately.
const changeNav = (entries, observer) = > {
entries.forEach((entry) = > {
// Check that the element collides
if(entry.isIntersecting && entry.intersectionRatio >= 0.55) {
// Remove the old Active style class
document.querySelector('.active').classList.remove('active');
// Get the target element ID that meets the condition
var id = entry.target.getAttribute('id');
// Find the matching element and add the class name
var newLink = document.querySelector(`[href="#${id}"] `).classList.add('active'); }}); }Copy the code
Browser support & Polyfill
For browsers that don’t yet support this feature, Polyfill fills the gap nicely. The official code and documentation can be found here: github.com/w3c/Interse…
An easier approach is to apply polyfill.io (polyfill.io). Polyfills can be individually specified to load and loaded only by browsers that meet the criteria. This allows for lightweight pages without too much configuration. Its usage is as follows:
<script src="https://polyfill.io/v2/polyfill.min.js? features=IntersectionObserver"></script>
Copy the code
Once Polyfill is loaded, the demos above will run in Safari, IE7+, and more.
conclusion
As you can see, the Intersection Observer API is easy to use and creative. Although Polyfill may be needed, browser support continues to improve. This API will be a great tool for front-end optimization.
–End–
Search fewelife concern public number reprint please indicate the source