How does the Intersection Observer API work?
Assesses fundamental understanding of JavaScript conventions, runtime behavior, and memory/performance considerations.
Hiring managers look for precision, avoidance of ambiguous jargon, and ability to explain trade-offs under real production conditions.
The Intersection Observer API provides a way to asynchronously observe changes in the intersection of a target element with an ancestor element or the viewport.
Basic usage:
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
console.log('Element is visible');
entry.target.classList.add('visible');
} else {
console.log('Element is not visible');
}
});
});
const target = document.querySelector('.observe-me');
observer.observe(target);
Lazy loading images:
const imageObserver = new IntersectionObserver((entries, observer) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
const img = entry.target;
img.src = img.dataset.src;
img.classList.add('loaded');
observer.unobserve(img); // Stop observing after loading
}
});
});
document.querySelectorAll('img[data-src]').forEach(img => {
imageObserver.observe(img);
});
Infinite scrolling:
const infiniteScroll = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
loadMoreContent();
}
});
}, {
rootMargin: '100px' // Trigger 100px before reaching the element
});
const sentinel = document.querySelector('.load-more-trigger');
infiniteScroll.observe(sentinel);
Options:
const options = {
root: null, // viewport (default)
rootMargin: '0px 0px -100px 0px', // Shrink observation area
threshold: [0, 0.25, 0.5, 0.75, 1] // Trigger at multiple visibility levels
};
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
console.log(`Visibility: ${entry.intersectionRatio * 100}%`);
});
}, options);
Tracking visibility time:
let visibilityStartTime;
const visibilityObserver = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
visibilityStartTime = Date.now();
} else if (visibilityStartTime) {
const visibilityDuration = Date.now() - visibilityStartTime;
console.log(`Element was visible for ${visibilityDuration}ms`);
visibilityStartTime = null;
}
});
});
Candidate Response Strategy & Interview Tips
- Start with a concise one-sentence summary: Deliver a direct, confident answer first before expanding into nuances.
- Demonstrate real-world trade-offs: Discuss where this approach excels and when you would avoid it in production systems.
- Discuss complexity & edge cases: Proactively explain time/space complexity or boundary conditions (null values, scale limits).
- Prepare for interviewer follow-ups: Technical hiring panels frequently probe deeper into concurrency, backward compatibility, or alternative libraries.