Intersection Observer API in JavaScript
Intersection Observer API in JavaScript
Description
The Intersection Observer API provides an asynchronous way to observe the intersection status of a target element with its ancestor element or the viewport. It can efficiently monitor whether an element enters or leaves the visible area, and is commonly used to implement features such as lazy loading of images, infinite scrolling, and exposure tracking.
Core Concepts
- Intersection Ratio: The ratio of the intersection area between the target element and the root element to the total area of the target element.
- Threshold: The intersection ratio value that triggers the callback function.
- Root Element: The ancestor element used as the reference frame, defaulting to the browser viewport.
Creating an Observer
// Create an observer instance
const observer = new IntersectionObserver(callback, options);
Detailed Explanation of Options Configuration
const options = {
root: null, // Root element, null means viewport
rootMargin: '0px', // Margin around the root element, used to expand or shrink the intersection area
threshold: [0, 0.5, 1] // Threshold values that trigger the callback when the intersection ratio reaches them
};
Callback Function Structure
const callback = (entries, observer) => {
entries.forEach(entry => {
// entry contains intersection information of the target element
console.log(entry.target); // The observed element
console.log(entry.isIntersecting); // Whether it is within the intersection area
console.log(entry.intersectionRatio); // Current intersection ratio
});
};
Complete Usage Example: Lazy Loading Images
// Create an observer
const lazyImageObserver = new IntersectionObserver((entries, observer) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
const img = entry.target;
// Assign the value of data-src to src
img.src = img.dataset.src;
// Stop observing after the image loads
img.onload = () => observer.unobserve(img);
}
});
}, {
threshold: 0.1, // Load when 10% of the image enters the viewport
rootMargin: '50px' // Start loading 50px in advance
});
// Observe all lazy-loading images
document.querySelectorAll('img[data-src]').forEach(img => {
lazyImageObserver.observe(img);
});
Advanced Application: Infinite Scrolling
let page = 1;
const sentinel = document.getElementById('sentinel'); // Sentinel element
const infiniteScrollObserver = new IntersectionObserver(async (entries) => {
if (entries[0].isIntersecting) {
// Load more content
const newContent = await loadMoreContent(page++);
appendContent(newContent);
}
});
infiniteScrollObserver.observe(sentinel);
Performance Advantages
- Asynchronous Execution: Does not block the main thread.
- Batch Processing: Multiple intersection changes are handled in a single callback.
- Automatic Optimization: The browser internally optimizes intersection detection.
Notes
- After creating the observer, you need to manually call
observe()to start observing. - Use
unobserve()to stop observing a specific element. - Use
disconnect()to stop all observations. - The root element must be an ancestor of the target element.
The Intersection Observer API solves performance issues related to scrolling and is an important tool in modern web development.