Skip to main content

IntersectionObserver

IntersectionObserver це вбудований API браузера, який дозволяє відстежувати, коли елемент потрапляє в область видимості (viewport) або виходить із неї, без важких обробників scroll. Це об'єкт, який «спостерігає» за елементом і повідомляє, коли той перетинається з областю перегляду або з іншим контейнером.

Теорія

TL;DR

  • IntersectionObserver стежить за перетином елемента з viewport або з заданим контейнером.
  • Це заміна scroll-подіям, ручним перевіркам getBoundingClientRect() і window.onscroll.
  • Створення: new IntersectionObserver(callback, options) плюс observer.observe(element).
  • Опції: root, rootMargin, threshold.
  • У колбек приходить масив IntersectionObserverEntry з isIntersecting, intersectionRatio, target.
  • Зупинка: observer.unobserve(target) для одного елемента, observer.disconnect() для всіх.

Швидкий приклад

javascript
const target = document.querySelector('#target'); const observer = new IntersectionObserver((entries) => { entries.forEach((entry) => { if (entry.isIntersecting) { console.log('Елемент з\'явився в зоні видимості!'); } else { console.log('Елемент вийшов із зони видимості!'); } }); }); observer.observe(target); // починаємо спостерігати

Простий приклад на сторінці

html
<div style="height: 120vh;"></div> <div id="target" style="height: 100px; background: coral;">Я ціль</div> <div style="height: 120vh;"></div> <script> const target = document.querySelector('#target'); const observer = new IntersectionObserver((entries) => { entries.forEach((entry) => { if (entry.isIntersecting) { console.log('Елемент з\'явився в зоні видимості!'); } else { console.log('Елемент вийшов із зони видимості!'); } }); }); observer.observe(target); // починаємо спостерігати </script>

Коли ви прокрутите сторінку і блок потрапить на екран, у консоль виведеться:

text
Елемент з'явився в зоні видимості!

Це чудова альтернатива:

  • подіям scroll;
  • ручним перевіркам через getBoundingClientRect();
  • обробникам window.onscroll, які сильно навантажують сторінку.

Параметри конструктора

javascript
new IntersectionObserver(callback, options);
ПараметрЩо робить
callbackФункція, яку викликають при кожному перетині
options.rootКонтейнер, усередині якого відстежувати (за замовчуванням вікно браузера)
options.rootMarginВідступи (наприклад '0px 0px -100px 0px'), як у CSS margin
options.thresholdПоріг спрацювання, частка видимості елемента (від 0 до 1)

Приклад з налаштуваннями:

javascript
const observer = new IntersectionObserver(callback, { root: null, // вікно браузера rootMargin: '0px 0px -100px 0px', // спрацює трохи раніше threshold: 0.5 // коли видно 50% елемента });

Об'єкт entry у колбеку

Кожен елемент, за яким стежить спостерігач, представлений об'єктом IntersectionObserverEntry:

javascript
entry.isIntersecting; // true / false entry.intersectionRatio; // частка видимої частини (від 0 до 1) entry.boundingClientRect; // положення елемента entry.rootBounds; // межі області видимості entry.target; // сам елемент

Колбек отримує саме масив таких записів, бо один спостерігач може стежити за сотнями елементів, і за один тік браузер віддає всі зміни разом.

Практичні приклади

Ліниве з'явлення елементів:

javascript
const items = document.querySelectorAll('.fade'); const observer = new IntersectionObserver((entries) => { entries.forEach((entry) => { if (entry.isIntersecting) { entry.target.classList.add('visible'); } }); }); items.forEach((item) => observer.observe(item));
css
.fade { opacity: 0; transform: translateY(20px); transition: 0.5s; } .fade.visible { opacity: 1; transform: translateY(0); }

Елементи плавно «випливають», коли потрапляють на екран.

Лінива загрузка зображень:

html
<img data-src="photo.jpg" alt="photo" width="400" height="300" />
javascript
const images = document.querySelectorAll('img[data-src]'); const observer = new IntersectionObserver((entries, obs) => { entries.forEach((entry) => { if (entry.isIntersecting) { const img = entry.target; img.src = img.dataset.src; obs.unobserve(img); // перестаємо стежити за цією картинкою } }); }); images.forEach((img) => observer.observe(img));

Тепер зображення завантажуються тільки тоді, коли стають видимими, а це економить трафік і пришвидшує завантаження сайту.

Переваги над scroll і керування спостереженням

Звичайний scrollIntersectionObserver
Викликає подію на кожному пікселі прокруткиПрацює асинхронно та ефективно
Треба вручну рахувати getBoundingClientRect()Усе рахує сам
Навантаження на CPUМайже нульове навантаження
Незручно з великою кількістю елементівОдин спостерігач стежить за сотнями елементів

Щоб перестати стежити за конкретним елементом:

javascript
observer.unobserve(target);

Щоб повністю вимкнути спостерігач:

javascript
observer.disconnect();

Підсумок:

Що робитьIntersectionObserver
ВідстежуєКоли елемент входить в область видимості або виходить з неї
Замінюєonscroll і getBoundingClientRect()
Використовується дляЛінивого завантаження, анімацій при скролі, аналітики переглядів
ПродуктивністьДуже висока, розрахунки робить браузер, а не ваш JS-код

Запам'ятайте просто: IntersectionObserver це «спостерігач за видимістю». Він повідомляє, коли елемент з'явився на екрані, і робить це ефективно, без зайвих подій scroll.

Типові помилки

  • Забувати викликати observer.observe(element). Створений спостерігач сам по собі ні за чим не стежить.
  • Чекати, що колбек спрацює лише при появі елемента. Він викликається і при виході з видимості, тому перевірка entry.isIntersecting обов'язкова.
  • Не викликати unobserve() після одноразової дії (наприклад підвантаження картинки) і виконувати роботу знову при кожному перетині.
  • Плутати threshold: 0 і threshold: 1: перший спрацьовує на першому пікселі елемента, другий лише коли видно весь елемент.
  • Задавати rootMargin у відсотках там, де потрібні пікселі, або взагалі без одиниць. Значення без одиниць браузер відхилить.
  • Використовувати root з елементом, який не є предком цілі. Спостереження тоді не працює так, як очікується.
  • Не відключати спостерігач при знищенні компонента (disconnect()), через що лишаються витоки пам'яті і колбеки для вже видалених вузлів.

Коротка відповідь

Для співбесіди
Premium

Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.