Поиск

Как отслеживать пересечение блока с областью просмотра через IntersectionObserver

Как отслеживать пересечение блока с областью просмотра через IntersectionObserver

IntersectionObserver сообщает о пересечении блока с заданной областью. Настройте корень и пороги, проверьте начальное событие и остановку наблюдения.

Что должно получиться

Сценарий получает уведомление, когда элемент пересекает нужную область или проходит заданную долю пересечения. Например, компонент отмечает первое появление в окне либо меняет состояние при входе и выходе. Для этого не нужно самостоятельно измерять положение каждого блока при каждом движении прокрутки.

Обычный IntersectionObserver оценивает геометрическое пересечение. Он не доказывает, что человек прочитал блок, и не гарантирует, что его не закрывает другой элемент. Поэтому заранее сформулируйте, какое событие действительно нужно вашей функции.

Из чего это складывается

ЧастьНазначениеЧто проверить
targetЭлемент, за которым наблюдаютУже существует и имеет нужную геометрию
rootОбласть сравненияОкно или подходящий предок элемента
rootMarginРасширяет или сужает область расчётаЗнак и стороны отступа соответствуют задаче
thresholdЗадаёт порог доли пересеченияОн достижим при размере блока
ОбработчикПолучает записи о пересеченииПроверяет состояние каждой записи
ОстановкаЗавершает ненужное наблюдениеСогласована с повторными действиями

Выбор области

При root: null ориентиром служит область просмотра документа. Если нужно следить за карточками внутри отдельного прокручиваемого контейнера, корнем можно назначить соответствующий элемент-предок. Проверьте, что цель действительно находится внутри выбранного корня.

RootMargin меняет область расчёта, а не реальные CSS-отступы элемента. Положительное значение расширяет соответствующую сторону области, отрицательное сужает. Поэтому уведомление может прийти ещё до появления блока в исходных границах окна. Подпись состояния должна соответствовать выбранной логике.

Как это сделать по шагам

  1. Определите результат: одно действие при первом пересечении или повторное изменение состояния при входе и выходе. Не смешивайте эти сценарии в одном условии без необходимости.
  2. Выберите целевой элемент и корень. Проверьте исходное положение, размеры и наличие вложенных прокручиваемых областей.
  3. Создайте IntersectionObserver с обработчиком и понятными параметрами. Начните с одного нужного порога вместо большого набора случайных значений.
  4. Подключите цель через observe. В обработчике просматривайте полученные записи и проверяйте isIntersecting вместе с необходимой долей пересечения.
  5. Проверьте первое уведомление сразу после начала наблюдения. Оно может описывать элемент, который ещё не пересекает область.
  6. Для разового действия остановите наблюдение после нужного результата. Для повторного сценария проверьте вход, выход и повторный вход.
  7. Проверьте смену размеров, быстрый переход по странице и удаление компонента. Уберите наблюдение, которое больше не нужно.

Пример разового действия

В учебном примере target — уже найденный элемент. Когда пересекается хотя бы четверть его площади, ему добавляется класс in-area и наблюдение за ним прекращается. Код: const watcher = new IntersectionObserver((entries, observer) => { for (const entry of entries) { if (entry.isIntersecting && entry.intersectionRatio >= 0.25) { entry.target.classList.add('in-area'); observer.unobserve(entry.target); } } }, { root: null, threshold: 0.25 }); watcher.observe(target);

Порог 0.25 выбран только для примера. Он относится к доле площади самого элемента, а не к четверти окна. Если элемент намного больше области просмотра, высокий порог может оказаться недостижимым. Подбирайте условие по действительной геометрии и задаче.

Этот пример делает одно действие. Если нужно убирать класс после выхода, не прекращайте наблюдение сразу и предусмотрите обе ветки состояния. При асинхронной работе отдельно решите, когда результат считается успешным и можно ли повторить попытку после ошибки.

Начальное уведомление и несколько записей

После observe обработчик получает начальное состояние, даже если прокрутки не было. Сам вызов обработчика не означает вход в область. Сначала посмотрите isIntersecting и значения нужной записи.

В одном вызове может быть несколько записей. Обрабатывайте каждую, а не только первый элемент массива. Если за одним наблюдателем закреплены разные цели, связывайте действие с entry.target.

Частые ошибки

Считать пересечение доказательством просмотра

Прямоугольники могут пересекаться, хотя блок закрыт панелью или человек не смотрит на страницу. Для оценки фактического внимания нужны другие условия и отдельная постановка задачи. Не называйте геометрическое событие чтением материала.

Ждать постоянного обновления каждого пикселя

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

Оставлять наблюдение после удаления компонента

При завершении работы вызовите unobserve для отдельной цели или disconnect для всего наблюдателя, если он больше не нужен. При повторном создании интерфейса не накапливайте старые подключения и повторные действия.

Делать тяжёлую работу в обработчике

Использование API не делает любой код быстрым автоматически. Если обработчик надолго занимает основной поток, интерфейс всё равно может задерживаться. Сохраняйте нужное состояние и отделяйте от уведомления работу, которой не требуется выполняться немедленно.

Как проверить

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

Для соседних задач пригодятся нативная загрузка изображений, проверка ошибок JavaScript и уменьшение движения. Помощь с поведением компонента можно найти в разделе «Разработка».

Вопросы и ответы

Почему обработчик вызван без прокрутки?

После начала наблюдения приходит запись о начальном состоянии. Проверьте её поля, прежде чем запускать действие.

Что означает intersectionRatio?

Это отношение площади пересечения к площади границ целевого элемента. Значение не описывает, какую часть всего окна занимает блок.

Можно ли использовать корнем внутренний контейнер?

Да, если это подходящий предок цели. Отдельно проверьте вложенную прокрутку и границы, которые участвуют в расчёте.

Почему высокий порог не достигается?

Элемент может быть слишком большим относительно области просмотра. Проверьте геометрию и выберите достижимое условие по задаче.

Как прекратить одно наблюдение?

Используйте unobserve для конкретной цели. Disconnect прекращает работу со всеми целями этого наблюдателя.

Заменяет ли пересечение подтверждение прочтения?

Нет. Геометрическое событие не доказывает внимание человека и не гарантирует отсутствие перекрывающих элементов.

—
01:21
26
Нет комментариев. Ваш будет первым!