Перевод не завершен. Пожалуйста, помогите перевести эту статью с английского.

Intersection Observer API позволяет веб-приложениям асинхронно следить за изменением пересечения элемента с его родителем или областью видимости документа viewport.

Исторически обнаружение видимости отдельного элемента или видимости двух элементов по отношению друг к другу было непростой задачей. Варианты решения этой задачи были ненадежными и замедляли работу браузера. К несчастью, по мере того как веб "взрослел", потребность в решении этой проблемы только росла по многим причинам, таким как:

  • Отложенная загрузка изображений или другого контента по мере прокрутки страницы.
  • Реализация веб-сайтов с "бесконечным скроллом", где контент подгружается по мере того как страница прокручивается вниз, и пользователю не нужно переключаться между страницами.
  • Отчет о видимости рекламы с целью посчитать доходы от нее.
  • Принятие решения, запускать ли какой-то процесс или анимацию в зависимости от того, увидит пользователь результат или нет.

В прошлом реализация обнаружения пересечения элементов подразумевала использование обработчиков событий и циклов, вызывающих методы типа Element.getBoundingClientRect(), чтобы собрать необходимую информацию о каждом затронутом элементе. Поскольку весь этот код работает в основном потоке, возникают проблемы с производительностью.

Рассмотрим веб-страницу с бесконечным скроллом. На ней используется библиотека для управления периодически размещаемой по всей странице рекламой, повсюду анимированная графика, а также библиотека для отображения всплывающих окон. И все эти вещи используют свои собственные правила для обнаружения пересечений, и все они запущены в основном потоке. Автор сайта может даже не подозревать об этой проблеме, а также может не знать, как работают сторонние библиотеки изнутри. В то же время пользователь по ходу прокрутки страницы сталкивается с тем, что работа сайта замедляется постоянным срабатыванием обнаружения пересечения, что в итоге приводит к тому, что пользователь недоволен браузером, сайтом и  своим компьютером.

Intersection Observer API даёт возможность зарегстрировать callback-функцию, которая выполнится при пересечении наблюдаемым элементом границ другого элемента (или области видимости документа 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().

Спецификации

Спецификация Статус Комментарий
Intersection Observer Рабочий черновик

Совместимость с браузерами

Update compatibility data on GitHub
КомпьютерыМобильные
ChromeEdgeFirefoxInternet ExplorerOperaSafariAndroid webviewChrome для AndroidFirefox для AndroidOpera для AndroidSafari on iOSSamsung Internet
IntersectionObserver
Экспериментальная
Chrome Полная поддержка 51Edge Полная поддержка 15Firefox Полная поддержка 55
Полная поддержка 55
Нет поддержки 53 — 55
Отключено
Отключено From version 53 until version 55 (exclusive): this feature is behind the dom.IntersectionObserver.enabled preference (needs to be set to true). To change preferences in Firefox, visit about:config.
IE Нет поддержки НетOpera Полная поддержка ДаSafari Полная поддержка 12.1WebView Android Полная поддержка 51Chrome Android Полная поддержка 51Firefox Android ? Opera Android ? Safari iOS Полная поддержка 12.2Samsung Internet Android Полная поддержка 5.0
IntersectionObserver() constructor
Экспериментальная
Chrome Полная поддержка 51Edge Полная поддержка 15Firefox Полная поддержка 55
Полная поддержка 55
Нет поддержки 53 — 55
Отключено
Отключено From version 53 until version 55 (exclusive): this feature is behind the dom.IntersectionObserver.enabled preference (needs to be set to true). To change preferences in Firefox, visit about:config.
IE Нет поддержки НетOpera ? Safari Полная поддержка 12.1WebView Android Полная поддержка 51Chrome Android Полная поддержка 51Firefox Android ? Opera Android ? Safari iOS Полная поддержка 12.2Samsung Internet Android Полная поддержка 5.0
root
Экспериментальная
Chrome Полная поддержка 51Edge Полная поддержка 15Firefox Полная поддержка 55
Полная поддержка 55
Нет поддержки 53 — 55
Отключено
Отключено From version 53 until version 55 (exclusive): this feature is behind the dom.IntersectionObserver.enabled preference (needs to be set to true). To change preferences in Firefox, visit about:config.
IE Нет поддержки НетOpera Полная поддержка ДаSafari Полная поддержка 12.1WebView Android Полная поддержка 51Chrome Android Полная поддержка 51Firefox Android ? Opera Android ? Safari iOS Полная поддержка 12.2Samsung Internet Android Полная поддержка 5.0
rootMargin
Экспериментальная
Chrome Полная поддержка 51Edge Полная поддержка 15Firefox Полная поддержка 55
Полная поддержка 55
Нет поддержки 53 — 55
Отключено
Отключено From version 53 until version 55 (exclusive): this feature is behind the dom.IntersectionObserver.enabled preference (needs to be set to true). To change preferences in Firefox, visit about:config.
IE Нет поддержки НетOpera Полная поддержка ДаSafari Полная поддержка 12.1
Замечания
Полная поддержка 12.1
Замечания
Замечания rootMargin does not work with <iframe>s.
WebView Android Полная поддержка 51Chrome Android Полная поддержка 51Firefox Android ? Opera Android ? Safari iOS Полная поддержка 12.2
Замечания
Полная поддержка 12.2
Замечания
Замечания rootMargin does not work with <iframe>s.
Samsung Internet Android Полная поддержка 5.0
thresholds
Экспериментальная
Chrome Полная поддержка 51Edge Полная поддержка 15Firefox Полная поддержка 55
Полная поддержка 55
Нет поддержки 53 — 55
Отключено
Отключено From version 53 until version 55 (exclusive): this feature is behind the dom.IntersectionObserver.enabled preference (needs to be set to true). To change preferences in Firefox, visit about:config.
IE Нет поддержки НетOpera Полная поддержка ДаSafari Полная поддержка 12.1WebView Android Полная поддержка 51Chrome Android Полная поддержка 51Firefox Android ? Opera Android ? Safari iOS Полная поддержка 12.2Samsung Internet Android Полная поддержка 5.0
disconnect
Экспериментальная
Chrome Полная поддержка 51Edge Полная поддержка 15
Замечания
Полная поддержка 15
Замечания
Замечания Available since Windows Insider Preview Build 14986
Firefox Полная поддержка 55
Полная поддержка 55
Нет поддержки 53 — 55
Отключено
Отключено From version 53 until version 55 (exclusive): this feature is behind the dom.IntersectionObserver.enabled preference (needs to be set to true). To change preferences in Firefox, visit about:config.
IE Нет поддержки НетOpera Полная поддержка ДаSafari ? WebView Android Полная поддержка 51Chrome Android Полная поддержка 51Firefox Android ? Opera Android ? Safari iOS ? Samsung Internet Android Полная поддержка 5.0
observe
Экспериментальная
Chrome Полная поддержка 51Edge Полная поддержка 15Firefox Полная поддержка 55
Полная поддержка 55
Нет поддержки 53 — 55
Отключено
Отключено From version 53 until version 55 (exclusive): this feature is behind the dom.IntersectionObserver.enabled preference (needs to be set to true). To change preferences in Firefox, visit about:config.
IE Нет поддержки НетOpera Полная поддержка ДаSafari Полная поддержка 12.1WebView Android Полная поддержка 51Chrome Android Полная поддержка 51Firefox Android ? Opera Android ? Safari iOS Полная поддержка 12.2Samsung Internet Android Полная поддержка 5.0
takeRecords
Экспериментальная
Chrome Полная поддержка 51Edge Полная поддержка 15
Замечания
Полная поддержка 15
Замечания
Замечания Available since Windows Insider Preview Build 14986
Firefox Полная поддержка 55
Полная поддержка 55
Нет поддержки 53 — 55
Отключено
Отключено From version 53 until version 55 (exclusive): this feature is behind the dom.IntersectionObserver.enabled preference (needs to be set to true). To change preferences in Firefox, visit about:config.
IE Нет поддержки НетOpera Полная поддержка ДаSafari ? WebView Android Полная поддержка 51Chrome Android Полная поддержка 51Firefox Android ? Opera Android ? Safari iOS ? Samsung Internet Android Полная поддержка 5.0
unobserve
Экспериментальная
Chrome Полная поддержка 51Edge Полная поддержка 15
Замечания
Полная поддержка 15
Замечания
Замечания Available since Windows Insider Preview Build 14986
Firefox Полная поддержка 55
Полная поддержка 55
Нет поддержки 53 — 55
Отключено
Отключено From version 53 until version 55 (exclusive): this feature is behind the dom.IntersectionObserver.enabled preference (needs to be set to true). To change preferences in Firefox, visit about:config.
IE Нет поддержки НетOpera Полная поддержка ДаSafari Полная поддержка 12.1WebView Android Полная поддержка 51Chrome Android Полная поддержка 51Firefox Android ? Opera Android ? Safari iOS Полная поддержка 12.2Samsung Internet Android Полная поддержка 5.0

Легенда

Полная поддержка  
Полная поддержка
Нет поддержки  
Нет поддержки
Совместимость неизвестна  
Совместимость неизвестна
Экспериментальная. Ожидаемое поведение может измениться в будущем.
Экспериментальная. Ожидаемое поведение может измениться в будущем.
Смотрите замечания реализации.
Смотрите замечания реализации.
Пользователь должен сам включить эту возможность.
Пользователь должен сам включить эту возможность.

Смотрите также

Метки документа и участники

Обновлялась последний раз: Tixxxon,