Syntax
new IntersectionObserver(callback, options).observe(element)Examples
Lazy-Loading Images
Loading an image only once it scrolls into view.
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
const img = entry.target;
img.src = img.dataset.src; // load the real image
observer.unobserve(img); // stop watching once loaded
}
});
});
document.querySelectorAll("img[data-src]").forEach(img => {
observer.observe(img);
});Triggering Animations on Scroll
Adding a class when an element becomes visible, with a threshold option.
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
entry.target.classList.add("fade-in");
}
});
}, { threshold: 0.5 }); // fires when 50% of the element is visible
document.querySelectorAll(".animate-on-scroll").forEach(el => {
observer.observe(el);
});Best practices
- Use IntersectionObserver instead of scroll event listeners for visibility detection - it is far more performant since the browser handles the calculation efficiently
- Call unobserve() once an element no longer needs watching (like after a lazy-loaded image has loaded), to free up resources
- Use the threshold option to control exactly what percentage of visibility should trigger the callback
- Use rootMargin to trigger the callback slightly before an element actually enters the viewport, for smoother lazy-loading
At a glance
- Purpose
- Application logic and interaction
- File extension
- .js ยท .mjs
- Runs in
- Browsers and JavaScript runtimes
- Usually used with
- HTML, CSS and Web APIs
Specifications & further reading
Related JavaScript documentation
DOM Selection: querySelector(), getElementById()
These methods find elements in the DOM. getElementById() finds a single element by its unique id, generally the fastest option. querySelector() finds the first element matching any valid CSS selector, and querySelectorAll() returns all matching elements as a static NodeList.Creating and Modifying Elements
createElement() builds a new DOM element in memory, which can then be customized and inserted into the page with methods like appendChild() or append(). textContent sets plain text safely, while innerHTML parses and inserts HTML markup - which carries injection risks if the content includes untrusted user input.classList: add, remove, toggle, contains
The classList property provides a convenient API for managing an element's CSS classes without manually parsing the className string. add() and remove() add or remove one or more classes, toggle() switches a class on or off based on its current presence, and contains() checks whether a class is currently applied.MutationObserver
MutationObserver watches for changes to the DOM tree - added/removed elements, attribute changes, or text content changes - and runs a callback in response. It is useful for reacting to DOM changes made by other scripts or third-party widgets that you do not directly control.
These methods find elements in the DOM. getElementById() finds a single element by its unique id, generally the fastest option. querySelector() finds the first element matching any valid CSS selector, and querySelectorAll() returns all matching elements as a static NodeList.Creating and Modifying Elements
createElement() builds a new DOM element in memory, which can then be customized and inserted into the page with methods like appendChild() or append(). textContent sets plain text safely, while innerHTML parses and inserts HTML markup - which carries injection risks if the content includes untrusted user input.classList: add, remove, toggle, contains
The classList property provides a convenient API for managing an element's CSS classes without manually parsing the className string. add() and remove() add or remove one or more classes, toggle() switches a class on or off based on its current presence, and contains() checks whether a class is currently applied.MutationObserver
MutationObserver watches for changes to the DOM tree - added/removed elements, attribute changes, or text content changes - and runs a callback in response. It is useful for reacting to DOM changes made by other scripts or third-party widgets that you do not directly control.