Intersection Observer API
Baseline Widely available *
This feature is well established and works across many devices and browser versions. It’s been available across browsers since March 2019.
* Some parts of this feature may have varying levels of support.
Intersection Observer API позволяет веб-приложениям асинхронно следить за изменением пересечения элемента с его родителем или областью видимости документа viewport.
Исторически обнаружение видимости отдельного элемента или видимости двух элементов по отношению друг к другу было непростой задачей. Варианты решения этой задачи были ненадёжными и замедляли работу браузера. К несчастью, по мере того как веб "взрослел", потребность в решении этой проблемы только росла по многим причинам, таким как:
- Отложенная загрузка изображений или другого контента по мере прокрутки страницы.
- Реализация веб-сайтов с "бесконечным скроллом", где контент подгружается по мере того как страница прокручивается вниз, и пользователю не нужно переключаться между страницами.
- Отчёт о видимости рекламы с целью посчитать доходы от неё.
- Принятие решения, запускать ли какой-то процесс или анимацию в зависимости от того, увидит пользователь результат или нет.
В прошлом реализация обнаружения пересечения элементов подразумевала использование обработчиков событий и циклов, вызывающих методы типа Element.getBoundingClientRect()
, чтобы собрать необходимую информацию о каждом затронутом элементе. Поскольку весь этот код работает в основном потоке, возникают проблемы с производительностью.
Рассмотрим веб-страницу с бесконечным скроллом. На ней используется библиотека для управления периодически размещаемой по всей странице рекламой, повсюду анимированная графика, а также библиотека для отображения всплывающих окон. И все эти вещи используют свои собственные правила для обнаружения пересечений, и все они запущены в основном потоке. Автор сайта может даже не подозревать об этой проблеме, а также может не знать, как работают сторонние библиотеки изнутри. В то же время пользователь по ходу прокрутки страницы сталкивается с тем, что работа сайта замедляется постоянным срабатыванием обнаружения пересечения, что в итоге приводит к тому, что пользователь недоволен браузером, сайтом и своим компьютером.
Intersection Observer API даёт возможность зарегистрировать колбэк-функцию, которая выполнится при пересечении наблюдаемым элементом границ другого элемента (или области видимости документа viewport), либо при изменении величины пересечения на определённое значение. Таким образом, больше нет необходимости вычислять пересечение элементов в основном потоке, и браузер может оптимизировать эти процессы на своё усмотрение.
Observer API не позволит узнать точное число пикселей или определить конкретные пиксели в пересечении; однако, его использование покрывает наиболее частые сценарии вроде "Если элементы пересекаются на N%, сделай то-то".
Основные понятия
Intersection Observer API позволяет указать функцию, которая будет вызвана всякий раз для элемента (target) при пересечении его с областью видимости документа (по умолчанию) или заданным элементом (root).
В основном, используется отслеживание пересечения элемента с областью видимости (необходимо указать null
в качестве корневого элемента).
Используете ли вы область видимости или другой элемент в качестве корневого, API работает одинаково, вызывая заданную вами колбэк-функцию, всякий раз, когда видимость целевого элемента изменяет так, что она пересекает в нужной степени корневой элемент.
Степень пересечения целевого и корневого элемента задаётся в диапазоне от 0.0 до 1.0, где 1.0 это полное пересечение целевого элемента границ корневого.
Пример использования
Для начала с помощью конструктора нужно создать объект-наблюдатель, указать для него функцию для вызова и настройки отслеживания:
var options = {
root: document.querySelector("#scrollArea"),
rootMargin: "0px",
threshold: 1.0,
};
var callback = function (entries, observer) {
/* Content excerpted, show below */
};
var observer = new IntersectionObserver(callback, options);
Параметр threshold со значением 1.0 означает что функция будет вызвана при 100% пересечении объекта (за которым мы следим) с объектом root
Настройки
- root
-
Элемент который используется в качестве области просмотра для проверки видимости целевого элемента. Должен быть предком целевого элемента. По умолчанию используется область видимости браузера если не определён или имеет значение null.
- rootMargin
-
Отступы вокруг root. Могут иметь значения как свойство css margin: "
10px 20px 30px 40px" (top, right, bottom, left).
Значения можно задавать в процентах. По умолчанию все параметры установлены в нули. - threshold
-
Число или массив чисел, указывающий, при каком проценте видимости целевого элемента должен сработать callback. Например, в этом случае callback функция будет вызываться при появлении в зоне видимости каждый 25% целевого элемента: [0, 0.25, 0.5, 0.75, 1]
Целевой элемент, который будет наблюдаться
После того, как вы создали наблюдателя, вам нужно дать ему целевой элемент для просмотра:
var target = document.querySelector("#listItem");
observer.observe(target);
Всякий раз, когда цель достигает порогового значения, указанного для IntersectionObserver
, вызывается колбэк-функция callback
. Где callback
получает список объектов IntersectionObserverEntry
и наблюдателя:
var callback = function (entries, observer) {
entries.forEach((entry) => {
entry.time; // a DOMHightResTimeStamp indicating when the intersection occurred.
entry.rootBounds; // a DOMRectReadOnly for the intersection observer's root.
entry.boundingClientRect; // a DOMRectReadOnly for the intersection observer's target.
entry.intersectionRect; // a DOMRectReadOnly for the visible portion of the intersection observer's target.
entry.intersectionRatio; // the number for the ratio of the intersectionRect to the boundingClientRect.
entry.target; // the Element whose intersection with the intersection root changed.
entry.isIntersecting; // intersecting: true or false
});
};
Обратите внимание, что колбэк-функция запускается в главном потоке и должна выполняться как можно быстрее, поэтому если что-то отнимает много времени, то используйте Window.requestIdleCallback()
.
Также обратите внимание, что если вы указали опцию root
, целевой элемент должен быть потомком корневого элемента.
Интерфейсы
IntersectionObserver
-
Основной интерфейс для API Intersection Observer. Предоставляет методы для создания и управления observer, который может наблюдать любое количество целевых элементов для одной и той же конфигурации пересечения. Каждый observer может асинхронно наблюдать изменения в пересечении между одним или несколькими целевыми элементами и общим элементом-предком или с их верхним уровнем
Document
's viewport. Предок или область просмотра упоминается как root. IntersectionObserverEntry
-
Описывает пересечение между целевым элементом и его корневым контейнером в определённый момент перехода. Объекты этого типа могут быть получены только двумя способами: в качестве входных данных для вашего колбэка IntersectionObserver или путём вызова
IntersectionObserver.takeRecords()
.
Спецификации
Specification |
---|
Intersection Observer # intersection-observer-interface |
Совместимость с браузерами
BCD tables only load in the browser