Как на JS реализовать «ленивое появление» (fade-in) элементов при прокрутке страницы с использованием Intersection Observer?
Intersection Observer API — это современный браузерный инструмент, позволяющий отслеживать момент, когда элемент попадает в зону видимости viewport. Это идеальное решение для реализации эффекта «ленивого появления» (fade-in) без постоянного прослушивания события scroll, что значительно повышает производительность.
## Шаг 1: Подготовка HTML
Добавьте класс к элементам, которые должны появляться:
html
## Шаг 2: CSS — начальное скрытое состояние
Элементы изначально должны быть прозрачными и, опционально, смещёнными:
css
.fade-element {
opacity: 0;
transform: translateY(30px);
transition: opacity 0.6s ease, transform 0.6s ease;
}
.fade-element.visible {
opacity: 1;
transform: translateY(0);
}
## Шаг 3: JavaScript с Intersection Observer
javascript
const elements = document.querySelectorAll(‘.fade-element’);
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
entry.target.classList.add(‘visible’);
observer.unobserve(entry.target); // отписываемся после срабатывания
}
});
}, {
threshold: 0.15 // элемент виден на 15%
});
elements.forEach(el => observer.observe(el));
## Разбор ключевых параметров
— **threshold** — число от 0 до 1, определяющее, какая доля элемента должна быть видна для срабатывания. Можно передать массив: `[0, 0.5, 1]`.
— **rootMargin** — отступы вокруг viewport (аналог CSS margin). Например, `’0px 0px -100px 0px’` запустит анимацию чуть раньше, чем элемент достигнет нижней границы экрана.
— **root** — по умолчанию `null` (весь viewport). Можно указать конкретный контейнер.
## Дополнительные улучшения
**Задержка для каскадного появления:**
javascript
elements.forEach((el, index) => {
el.style.transitionDelay = `${index * 0.1}s`;
observer.observe(el);
});
**Повторное появление при возврате к элементу:**
Если нужно, чтобы анимация срабатывала каждый раз, уберите `observer.unobserve()` и добавьте удаление класса при выходе из зоны видимости:
javascript
if (entry.isIntersecting) {
entry.target.classList.add(‘visible’);
} else {
entry.target.classList.remove(‘visible’);
}
## Поддержка браузеров
Intersection Observer поддерживается всеми современными браузерами. Для старых (IE11) потребуется полифилл: `intersection-observer` из npm или CDN.
Такой подход значительно эффективнее слушателя события `scroll`, так как не блокирует главный поток и не вызывает лишних перерасчётов макета.
