JavaScript IntersectionObserver — коли елемент з'явився на екрані


IntersectionObserver (спостерігач перетину) повідомляє, коли елемент з'явився в полі зору або зник із нього.

автор: NagarD

Загальний опис

Раніше це робили обробником scroll: на кожен піксель прокрутки бігали по елементах і рахували координати через getBoundingClientRect(). Це били десятки разів на секунду, перераховували макет і різали продуктивність — сторінка «смикалась» при прокрутці.

Спостерігач працює інакше: він асинхронний і живе поза головним потоком. Браузер сам знає, що куди перетнулось, і просто повідомляє — без жодних обчислень із твого боку.

Звідси три класичні застосування: ліниве завантаження зображень, нескінченна стрічка (спостерігаємо за «маячком» у кінці списку) і анімації появи блоків.

Поріг threshold каже, яку частку елемента вважати видимою: 0 — щойно з'явився край, 1 — видно повністю.

автор: NagarD

Порада

Одноразові речі (підвантажити картинку, програти анімацію) не забувай знімати: observer.unobserve(element) після спрацювання — інакше платитимеш за спостереження вічно.

автор: NagarD

Синтаксис

const observer = new IntersectionObserver(callback, options);

властивості

Властивість Опис
root Елемент-область перетину (null — вікно).
rootMargin Відступи області перетину.
thresholds Пороги видимості, на яких спрацьовує колбек.

методи

Метод Опис
observe Починає стежити за елементом.
unobserve Припиняє стежити за елементом.
disconnect Припиняє стежити за всіма.

Переглядачі

Підтримка: стаціонарні переглядачі
Переглядач Google Chrome Mozilla Firefox Apple Safari Opera Microsoft EDGE Microsoft Internet Explorer
IntersectionObserver 51+ 55+ 12.1+ 38+ 15+ -
Підтримка: мобільні переглядачі
Переглядач Mobile Google Android Mobile Google Chrome Mobile Mozilla Firefox Mobile Apple Safari
IntersectionObserver 51+ yes yes 12.2+

Приклади

+ запропонувати свій приклад у пісочниці

Ліниве завантаження й нескінченна стрічка — без обробника scroll.

HTML

<img data-src="/img/logo.svg" alt="">
<div id="sentinel"></div>

JS

const lazy = new IntersectionObserver((entries, observer) => {
    for (const entry of entries) {
        if (!entry.isIntersecting) {
            continue;
        }

        const img = entry.target;
        img.src = img.dataset.src;

        // спрацювало один раз — більше не спостерігаємо
        observer.unobserve(img);
    }
}, {
    // почати вантажити за 200px ДО появи на екрані
    rootMargin: '200px',
});

document.querySelectorAll('img[data-src]').forEach(img => lazy.observe(img));

// нескінченна стрічка: маячок у кінці списку
const more = new IntersectionObserver(entries => {
    if (entries[0].isIntersecting) {
        loadNextPage();
    }
});

more.observe(document.getElementById('sentinel'));
автор: NagarD

Коментарі

Коментарів ще немає — будьте першим!

Відповідь для

Увійдіть — коментар з'явиться одразу, без капчі й очікування перевірки.

Пропозиція правки

Ваша версія — : після перевірки замінить чинну. Нова порада чи нотатка — з'явиться на сторінці після перевірки.

Ви гість — діють добові ліміти. Увійдіть, щоб пропонувати без капчі.

Ваша версія секції «»: після перевірки замінить чинну.

Ви гість — діють добові ліміти. Увійдіть, щоб пропонувати без капчі.

Ваша версія опису «»: після перевірки замінить чинну.

Ви гість — діють добові ліміти. Увійдіть, щоб пропонувати без капчі.

Зворотний зв'язок
Вхід