Intersection Observer API позволяет отслеживать пересечение одного элемента с другим или с областью видимости браузера, что делает возможным эффективное управление ленивой загрузкой контента, анимациями при прокрутке и оптимизацией производительности. Основная идея заключается в том, чтобы наблюдать за элементом и получать уведомления при его появлении или исчезновении из видимой области.
API работает через объект IntersectionObserver, который
создается с помощью конструктора:
const observer = new IntersectionObserver(callback, options);
const options = {
root: null, // Элемент-контейнер, относительно которого проверяется видимость. null = viewport.
rootMargin: '0px', // Отступы вокруг root, можно использовать px или %.
threshold: 0 // Процент видимости элемента для срабатывания callback (0–1 или массив).
};
root — родительский элемент для отслеживания. Если
null, то отслеживание ведется относительно окна
браузера.rootMargin — позволяет расширять или сужать область
наблюдения, например '0px 0px -100px 0px' сдвигает нижнюю
границу вверх на 100 пикселей.threshold — указывает, при каком проценте видимости
элемента вызывается callback. Может быть числом или массивом чисел, что
позволяет получать уведомления при нескольких стадиях видимости.Callback получает два аргумента:
entries — массив объектов
IntersectionObserverEntry.observer — ссылка на сам наблюдатель.Объект IntersectionObserverEntry содержит ключевые
свойства:
target — элемент, за которым ведется наблюдение.isIntersecting — булевое значение, указывающее, пересек
ли элемент наблюдаемую область.intersectionRatio — процент видимой части элемента (от
0 до 1).boundingClientRect — размеры и позиция элемента.intersectionRect — пересекающаяся часть элемента с
областью root.Пример базового использования:
const callback = (entries, observer) => {
entries.forEach(entry => {
if(entry.isIntersecting) {
entry.target.classList.add('visible');
observer.unobserve(entry.target); // прекращает наблюдение
}
});
};
const observer = new IntersectionObserver(callback, { threshold: 0.5 });
document.querySelectorAll('.animate').forEach(el => observer.observe(el));
Intersection Observer идеально подходит для отложенной загрузки изображений. Вместо того чтобы грузить все изображения сразу, их можно загружать по мере появления в зоне видимости:
const images = document.querySelectorAll('img[data-src]');
const loadImage = (entry) => {
const img = entry.target;
img.src = img.dataset.src;
img.removeAttribute('data-src');
};
const imgObserver = new IntersectionObserver((entries, observer) => {
entries.forEach(entry => {
if(entry.isIntersecting) {
loadImage(entry);
observer.unobserve(entry.target);
}
});
}, { threshold: 0.1 });
images.forEach(img => imgObserver.observe(img));
Для создания эффектов появления или прокрутки можно добавлять классы при пересечении элементов с viewport:
const sections = document.querySelectorAll('.section');
const revealSection = (entries, observer) => {
entries.forEach(entry => {
if(entry.isIntersecting) {
entry.target.classList.add('reveal');
observer.unobserve(entry.target);
}
});
};
const sectionObserver = new IntersectionObserver(revealSection, { threshold: 0.2 });
sections.forEach(section => sectionObserver.observe(section));
Такой подход уменьшает нагрузку на браузер, так как анимации запускаются только для видимых элементов.
unobserve(target) прекращает наблюдение за конкретным
элементом, что уменьшает расход ресурсов.disconnect()
прекращает наблюдение за всеми элементами.unobserve после достижения цели.При реализации плавного скролла (smooth scroll)
Intersection Observer позволяет запускать анимации, изменять активные
ссылки в меню и подгружать контент синхронно с прокруткой, обеспечивая
динамичное и отзывчивое взаимодействие с пользователем без постоянного
опроса позиции элементов через scroll события. Это особенно
важно для современных интерфейсов с длинными лендинговыми страницами и
параллакс-эффектами.