Перейти к содержимому

75. Intersection Observer

Иллюстрация к уроку Intersection Observer API позволяет отслеживать, когда элемент становится видимым в окне браузера (viewport) или внутри другого элемента. Это мощный инструмент для оптимизации производительности и создания интерактивных пользовательских интерфейсов.

Представьте, что у вас есть охранник, который следит за конкретным объектом (элементом на странице). Как только часть этого объекта попадает в поле зрения охранника (viewport или другой элемент), охранник подает сигнал. Intersection Observer – это и есть этот охранник в мире JavaScript. Он асинхронно следит за пересечением целевого элемента с другим элементом (корнем или viewport).

Давайте создадим простой пример, где мы будем добавлять класс visible к элементу, когда он становится видимым в viewport.

<!DOCTYPE html>
<html>
<head>
<title>Intersection Observer Example</title>
<style>
.box {
width: 200px;
height: 200px;
background-color: lightblue;
margin-bottom: 500px; /* Чтобы контент прокручивался */
}
.visible {
background-color: lightgreen;
}
</style>
</head>
<body>
<div class="box">Этот блок будет изменять цвет, когда станет видимым.</div>
<script>
const box = document.querySelector('.box');
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
box.classList.add('visible');
observer.unobserve(box); // Прекращаем наблюдение, когда элемент стал видимым
} else {
box.classList.remove('visible'); // Удаляем класс, если элемент снова невидим
}
});
});
observer.observe(box);
</script>
</body>
</html>

В этом примере:

  1. Мы создаем новый IntersectionObserver.
  2. В колбэк-функции мы проверяем свойство isIntersecting каждого entry. isIntersecting равно true, если элемент пересекается с viewport.
  3. Если элемент видим, мы добавляем класс visible и прекращаем наблюдение, чтобы не выполнять колбэк при каждом изменении видимости. Это оптимизация.
  4. Мы начинаем наблюдение за элементом box с помощью observer.observe(box).

Мы можем настроить IntersectionObserver, передав ему объект с параметрами.

const options = {
root: null, // Элемент, относительно которого происходит пересечение (null = viewport)
rootMargin: '0px', // Отступы вокруг root
threshold: 0.5 // Порог видимости (0.0 - 1.0). 0.5 означает, что 50% элемента должны быть видны.
};
const observer = new IntersectionObserver((entries) => {
// ...
}, options);
  • root: Определяет элемент, который используется как область просмотра для отслеживания видимости целевого элемента. Если указать null (значение по умолчанию), используется viewport браузера.
  • rootMargin: Добавляет отступы вокруг root. Можно использовать значения в px или %. Например, rootMargin: '100px 0px 100px 0px' добавит отступы сверху и снизу в 100px.
  • threshold: Определяет, какой процент целевого элемента должен быть видим, чтобы колбэк был вызван. Значение от 0.0 до 1.0.

Intersection Observer широко используется в реальных проектах для:

  • Ленивой загрузки изображений: Загрузка изображений только когда они становятся видимыми в viewport, что значительно улучшает производительность страницы.
  • Реализации бесконечной прокрутки (infinite scroll): Подгрузка новых данных по мере приближения к концу страницы.
  • Анимации при прокрутке: Запуск анимации, когда элемент появляется в viewport.
  • Отслеживания видимости рекламы: Для аналитики и показа рекламы только когда она видна пользователю.
  • Многие фреймворки и библиотеки используют Intersection Observer для оптимизации рендеринга компонентов. Например, React-lazyload использует его для ленивой загрузки компонентов.
  • Intersection Observer API предоставляет эффективный способ отслеживать видимость элементов.
  • Он работает асинхронно, что не блокирует основной поток выполнения JavaScript.
  • root, rootMargin и threshold позволяют гибко настраивать условия срабатывания колбэка.
  • Intersection Observer помогает оптимизировать производительность и создавать более интерактивные пользовательские интерфейсы.
  • Важно прекращать наблюдение за элементом, когда оно больше не требуется, чтобы избежать ненужных вызовов колбэка.