Spec-Zone.ru › Web APIs

API наблюдателя пересечения

Базовая Широко доступна *

Эта функция хорошо зарекомендовала себя и работает на многих устройствах и версиях браузеров. Она доступна в браузерах с марта 2019 года.

* Некоторые части этой функции могут иметь разный уровень поддержки.

  • Подробнее
  • Полная совместимость
  • Отправить отзыв

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

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

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

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

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

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

Одного чего не может сделать API наблюдателя пересечения: это вызвать логику на основе точного числа перекрывающихся пикселей или конкретно на которых. Он решает только обычный случай: «Если они пересекаются примерно на N%, мне нужно сделать что-то».

Концепции и использование наблюдателя пересечения

API наблюдателя пересечения позволяет настроить обратный вызов, который вызывается при наступлении любого из этих обстоятельств:

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

Обычно вы захотите следить за изменениями пересечения относительно ближайшего предкового элемента с возможностью прокрутки целевого элемента или, если целевой элемент не является потомком элемента с прокруткой, относительно поля просмотра устройства. Чтобы следить за пересечением относительно поля просмотра устройства, укажите null для опции root. Читайте дальше для более подробного объяснения опций наблюдателя пересечения.

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

Степень пересечения между целевым элементом и его корнем — это коэффициент пересечения. Это представление процента целевого элемента, видимого как значение от 0,0 до 1,0.

Создание наблюдателя пересечения

Создайте наблюдателя пересечения, вызвав его конструктор и передав ему функцию обратного вызова, которая будет выполняться всякий раз, когда порог пересечения будет пересечен в одном или другом направлении:

const options = {
  root: document.querySelector("#scrollArea"),
  rootMargin: "0px",
  threshold: 1.0,
};

const observer = new IntersectionObserver(callback, options);

Порог в 1,0 означает, что когда 100% целевого элемента видимы в элементе, указанном в опции root, вызывается обратный вызов.

Опции наблюдателя пересечения

Объект options, передаваемый в конструктор IntersectionObserver(), позволяет контролировать обстоятельства, при которых вызывается обратный вызов наблюдателя. У него есть следующие поля:

root

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

rootMargin

Отступ вокруг корня. Строка от одного до четырех значений, аналогичная свойству CSS margin, например, "10px 20px 30px 40px" (верх, право, низ, лево). Значения могут быть только абсолютными длинами или процентами. Этот набор значений служит для увеличения или уменьшения каждой стороны области отрисовки корневого элемента перед вычислением пересечений. Отрицательные значения уменьшат область отрисовки корневого элемента, а положительные — увеличат. Значение по умолчанию, если не указано, — "0px 0px 0px 0px".

threshold

Либо одно число, либо массив чисел, которые указывают, при каком проценте видимости цели должен быть выполнен обратный вызов наблюдателя. Если вы хотите обнаружить только то, что видимость превысила 50%, вы можете использовать значение 0,5. Если вы хотите, чтобы обратный вызов выполнялся каждый раз, когда видимость превышает еще на 25%, вы бы указали массив [0, 0,25, 0,5, 0,75, 1]. По умолчанию — 0 (что означает, что как только хотя бы один пиксель становится видимым, обратный вызов будет выполнен). Значение 1,0 означает, что порог не считается пройденным до тех пор, пока не будет виден каждый пиксель.

Обратные вызовы изменений пересечения

Обратный вызов, переданный в конструктор IntersectionObserver(), получает список объектов IntersectionObserverEntry и наблюдателя:

const callback = (entries, observer) => {
  entries.forEach((entry) => {
    // Each entry describes an intersection change for one observed
    // target element:
    //   entry.boundingClientRect
    //   entry.intersectionRatio
    //   entry.intersectionRect
    //   entry.isIntersecting
    //   entry.rootBounds
    //   entry.target
    //   entry.time
  });
};

Список записей, получаемых обратным вызовом, содержит по одному объекту IntersectionObserverEntry для каждого события пересечения порога — сразу могут быть получены несколько записей, либо от нескольких целей, либо от одной цели, пересекающей несколько порогов за короткий промежуток времени. Записи передаются с помощью очереди, поэтому они должны быть отсортированы по времени их создания, но вы предпочтительно должны использовать IntersectionObserverEntry.time для их правильной сортировки. Каждая запись описывает, сколько заданного элемента пересекается с корневым элементом, считается ли элемент пересекающимся или нет и т. д. Запись содержит только информацию об этом конкретном моменте — если вам нужна информация, требующая отслеживания во времени, например, направление и скорость прокрутки, вам может потребоваться вычислить её самостоятельно, запомнив ранее полученные записи.

Обратите внимание, что ваш обратный вызов выполняется в основном потоке. Он должен работать как можно быстрее; если необходимо выполнить какую-либо длительную задачу, используйте Window.requestIdleCallback().

Приведенный ниже фрагмент кода показывает обратный вызов, который хранит счетчик того, сколько раз элементы переходят от непересечения корня к пересечению не менее чем на 75%. При значении порога 0,0 (по умолчанию) обратный вызов вызывается приблизительно при изменении булевого значения isIntersecting. Таким образом, фрагмент кода сначала проверяет, является ли переход положительным, а затем определяет, является ли intersectionRatio выше 75%, в этом случае он увеличивает счетчик.

const intersectionCallback = (entries) => {
  entries.forEach((entry) => {
    if (entry.isIntersecting) {
      let elem = entry.target;

      if (entry.intersectionRatio >= 0.75) {
        intersectionCounter++;
      }
    }
  });
};

Назначение элемента для наблюдения

После создания наблюдателя вам необходимо указать ему целевой элемент для наблюдения:

const target = document.querySelector("#listItem");
observer.observe(target);

// the callback we set up for the observer will be executed now for the first time
// it waits until we assign a target to our observer (even if the target is currently not visible)

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

Также обратите внимание, что если вы указали опцию root, цель должна быть потомком корневого элемента.

Как вычисляется пересечение

Все области, рассматриваемые API Intersection Observer, представляют собой прямоугольники; элементы, имеющие неправильную форму, рассматриваются как занимающие наименьший прямоугольник, который охватывает все части элемента. Аналогично, если видимая часть элемента не является прямоугольной, прямоугольник пересечения элемента считается наименьшим прямоугольником, содержащим все видимые части элемента.

Полезно немного узнать о том, как различные свойства, предоставляемые IntersectionObserverEntry, описывают пересечение.

Корень пересечения и отступ корня

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

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

  • Если корень пересечения — это неявный корень (то есть корень верхнего уровня Document), прямоугольник пересечения корня — это прямоугольник области просмотра.
  • Если корень пересечения имеет обрезку overflow, прямоугольник пересечения корня — это область содержимого корневого элемента.
  • В противном случае прямоугольник пересечения корня — это прямоугольник границ клиентского элемента корня пересечения (полученный вызовом getBoundingClientRect() к нему).

Прямоугольник пересечения корня можно дополнительно настроить, задав отступ корня, rootMargin, при создании IntersectionObserver. Значения в rootMargin определяют смещения, добавляемые к каждой стороне прямоугольника границ корня пересечения для создания конечных границ корня пересечения (которые раскрываются в IntersectionObserverEntry.rootBounds при выполнении обратного вызова). Положительные значения увеличивают прямоугольник, а отрицательные — уменьшают его.

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

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

Пороговые значения

Вместо того чтобы сообщать о каждом бесконечно малом изменении степени видимости целевого элемента, API Intersection Observer использует пороговые значения. При создании наблюдателя вы можете указать одно или несколько числовых значений, представляющих процент видимости целевого элемента. Затем API сообщает только о переходах через эти пороговые значения.

Например, если вы хотите получать уведомления каждый раз, когда видимость цели проходит назад или вперед через каждую отметку 25%, вы бы указали массив [0, 0.25, 0.5, 0.75, 1] в качестве списка пороговых значений при создании наблюдателя.

Когда вызывается обратный вызов, он получает список IntersectionObserverEntry объектов, по одному для каждой наблюдаемой цели, у которой изменилась степень пересечения с корнем таким образом, что количество видимой части перешло через одно из пороговых значений в любом направлении.

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

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

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

  • Первый прямоугольник имеет пороговое значение для каждого процента видимости; то есть, массив IntersectionObserver.thresholds [0.00, 0.01, 0.02, /*…,*/ 0.99, 1.00].
  • Второй прямоугольник имеет единственное пороговое значение на отметке 50%.
  • Третий прямоугольник имеет пороговые значения каждые 10% видимости (0%, 10%, 20% и т. д.).
  • Последний прямоугольник имеет пороговые значения каждые 25%.

Обрезка и прямоугольник пересечения

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

  1. Прямоугольник границ целевого элемента (то есть наименьший прямоугольник, полностью охватывающий прямоугольники границ всех компонентов, составляющих элемент) получается путем вызова getBoundingClientRect() для целевого элемента. Это максимальный размер прямоугольника пересечения. Остальные шаги удалят любые части, которые не пересекаются.
  2. Начиная с непосредственного родительского блока целевого элемента и двигаясь наружу, обрезка каждого содержащего блока (если она есть) применяется к прямоугольнику пересечения. Обрезка блока определяется на основе пересечения двух блоков и режима обрезки (если он есть), указанного свойством overflow. Установка overflow на значение, отличное от visible , приводит к обрезке.
  3. Если один из содержащих элементов является корнем вложенного контекста просмотра (например, документ, содержащийся в <iframe>), прямоугольник пересечения обрезается до области просмотра содержащего контекста, и рекурсия вверх по контейнерам продолжается с содержащим блоком контейнера. Таким образом, если достигнут верхний уровень <iframe> , прямоугольник пересечения обрезается до области просмотра фрейма, а затем родительский элемент фрейма является следующим блоком, который рекурсивно проходит к корню пересечения.
  4. Когда рекурсия вверх достигает корня пересечения, полученный прямоугольник отображается в системе координат корня пересечения.
  5. Полученный прямоугольник затем обновляется путем пересечения его с прямоугольником пересечения корня.
  6. Этот прямоугольник, наконец, отображается в системе координат document целевого элемента.

Интерфейсы

IntersectionObserver

Основной интерфейс API Intersection Observer. Предоставляет методы для создания и управления наблюдателем, который может отслеживать любое количество целевых элементов для одной и той же конфигурации пересечения. Каждый наблюдатель может асинхронно наблюдать за изменениями в пересечении между одним или несколькими целевыми элементами и общим предковым элементом или областью просмотра верхнего уровня Document. Предок или область просмотра называется корнем.

IntersectionObserverEntry

Описание пересечения между целевым элементом и контейнером корня в определенный момент перехода. Объекты этого типа могут быть получены только двумя способами: как входные данные для вашего IntersectionObserver обратного вызова или путем вызова IntersectionObserver.takeRecords().

Простой пример

В этом простом примере целевой элемент изменяет свой цвет и прозрачность по мере того, как он становится более или менее видимым. В Определении времени видимости элемента с помощью API Intersection Observer можно найти более подробный пример, демонстрирующий, как определить продолжительность видимости набора элементов (например, рекламы) для пользователя и как реагировать на эту информацию, записывая статистику или обновляя элементы.

HTML

HTML для этого примера очень короткий, с основным элементом, который является областью, на которую мы будем нацеливаться (с творческим идентификатором "box"), и некоторым содержимым внутри области.

<div id="box">
  <div class="vertical">Welcome to <strong>The Box!</strong></div>
</div>

CSS

CSS не очень важен для целей этого примера; он выстраивает элемент и устанавливает, что атрибуты background-color и border могут участвовать в переходах CSS, которые мы будем использовать для изменения элемента по мере того, как он становится более или менее скрытым.

#box {
  background-color: rgb(40 40 190 / 100%);
  border: 4px solid rgb(20 20 120);
  transition:
    background-color 1s,
    border 1s;
  width: 350px;
  height: 350px;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
}

.vertical {
  color: white;
  font: 32px "Arial";
}

.extra {
  width: 350px;
  height: 350px;
  margin-top: 10px;
  border: 4px solid rgb(20 20 120);
  text-align: center;
  padding: 20px;
}

JavaScript

Наконец, давайте посмотрим на код JavaScript, использующий API Intersection Observer для реализации нужного эффекта.

Настройка

Сначала нам нужно подготовить переменные и установить наблюдатель.

const numSteps = 20.0;

let boxElement;
let prevRatio = 0.0;
let increasingColor = "rgb(40 40 190 / ratio)";
let decreasingColor = "rgb(190 40 40 / ratio)";

// Set things up
window.addEventListener(
  "load",
  (event) => {
    boxElement = document.querySelector("#box");

    createObserver();
  },
  false,
);

Константы и переменные, которые мы здесь настроили:

numSteps

Константа, указывающая, сколько порогов мы хотим иметь между коэффициентом видимости 0,0 и 1,0.

prevRatio

Эта переменная будет использоваться для записи того, каков был коэффициент видимости в последний раз, когда был пересечён порог; это позволит нам определить, становится ли целевой элемент более или менее видимым.

increasingColor

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

decreasingColor

Аналогично, это строка, определяющая цвет, который мы применим, когда коэффициент видимости уменьшается.

Мы вызываем Window.addEventListener() для начала прослушивания события load; после завершения загрузки страницы мы получаем ссылку на элемент с идентификатором "box" с помощью querySelector(), а затем вызываем метод createObserver() , который мы создадим вскоре для обработки создания и установки наблюдателя пересечения.

Создание наблюдателя пересечения

Метод createObserver() вызывается после завершения загрузки страницы для фактического создания нового IntersectionObserver и запуска процесса наблюдения за целевым элементом.

function createObserver() {
  let observer;

  let options = {
    root: null,
    rootMargin: "0px",
    threshold: buildThresholdList(),
  };

  observer = new IntersectionObserver(handleIntersect, options);
  observer.observe(boxElement);
}

Это начинается с настройки объекта options, содержащего параметры наблюдателя. Мы хотим отслеживать изменения видимости целевого элемента относительно области просмотра документа, поэтому root равно null. Нам не нужен отступ, поэтому отступ отступа rootMargin задан как "0px". Это заставляет наблюдатель отслеживать изменения пересечения границ целевого элемента и области просмотра без добавления (или вычитания) пространства.

Список пороговых значений коэффициента видимости, threshold, создаётся функцией buildThresholdList(). В этом примере список порогов создаётся программно, так как их много, и предполагается, что количество можно настраивать.

После того как options готов, мы создаём новый наблюдатель, вызывая конструктор IntersectionObserver(), определяя функцию, которая должна вызываться при пересечении одного из наших порогов, handleIntersect(), и наш набор параметров. Затем мы вызываем observe() на возвращённом наблюдателе, передавая в него желаемый целевой элемент.

Мы можем отслеживать видимость пересечения нескольких элементов относительно области просмотра, вызвав observer.observe() для каждого из этих элементов, если это необходимо.

Создание массива пороговых коэффициентов

Функция buildThresholdList(), которая создаёт список порогов, выглядит следующим образом:

function buildThresholdList() {
  let thresholds = [];
  let numSteps = 20;

  for (let i = 1.0; i <= numSteps; i++) {
    let ratio = i / numSteps;
    thresholds.push(ratio);
  }

  thresholds.push(0);
  return thresholds;
}

Это создаёт массив порогов — каждый из которых является коэффициентом между 0,0 и 1,0, путём добавления значения i/numSteps в массив thresholds для каждого целого числа i от 1 до numSteps. Также добавляется 0 для включения этого значения. Результат, учитывая значение по умолчанию numSteps (20), — следующий список порогов:

# Коэффициент # Коэффициент
0 0,05 11 0,6
1 0,1 12 0,65
2 0,15 13 0,7
3 0,2 14 0,75
4 0,25 15 0,8
5 0,3 16 0,85
6 0,35 17 0,9
7 0,4 18 0,95
8 0,45 19 1
9 0,5 20 0
10 0,55

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

Обработка изменений пересечения

Когда браузер обнаруживает, что целевой элемент (в нашем случае, элемент с идентификатором "box") был раскрыт или скрыт таким образом, что его коэффициент видимости пересекает один из порогов в нашем списке, он вызывает нашу обработчик функцию, handleIntersect():

function handleIntersect(entries, observer) {
  entries.forEach((entry) => {
    if (entry.intersectionRatio > prevRatio) {
      entry.target.style.backgroundColor = increasingColor.replace(
        "ratio",
        entry.intersectionRatio,
      );
    } else {
      entry.target.style.backgroundColor = decreasingColor.replace(
        "ratio",
        entry.intersectionRatio,
      );
    }

    prevRatio = entry.intersectionRatio;
  });
}

Для каждого IntersectionObserverEntry в списке entries, мы проверяем, увеличивается ли intersectionRatio записи; если это так, мы устанавливаем background-color целевого элемента в строку из increasingColor (помните, это "rgb(40 40 190 / ratio)"), заменяет слово "коэффициент" на intersectionRatio. Результат: цвет не только изменяется, но и изменяется прозрачность целевого элемента; по мере уменьшения коэффициента пересечения значение альфа-канала цвета фона уменьшается вместе с ним, что приводит к элементу, который становится более прозрачным.

Аналогично, если intersectionRatio уменьшается, мы используем строку decreasingColor и заменяем в ней слово "коэффициент" на intersectionRatio перед установкой background-color целевого элемента.

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

Результат

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

В Timing element visibility with the Intersection Observer API есть ещё более подробный пример.

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

Спецификация
Наблюдатель пересечения
# intersection-observer-interface

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

Настольный Мобильный
Chrome Edge Firefox Opera Safari Chrome Android Firefox for Android Opera Android Safari на IOS Samsung Internet WebView Android
IntersectionObserver 51 15
55До версии 96 конструктор выдает DOMException если параметр options.rootMargin передается как пустая строка (см. bug 1738791).
38 12.1 51 55 41 12.2 5.0 51
Intersection_Observer_API 51 15 55 38 12.1 51 55 41 12.2 5.0 51
delay 74 79 Нет 62 Нет 74 Нет 53 Нет 11.0 74
disconnect 51
15Доступно начиная с Windows Insider Preview Build 14986.
55 38 12.1 51 55 41 12.2 5.0 51
observe 51 15 55 38 12.1 51 55 41 12.2 5.0 51
root 51 15 55 38 12.1 51 55 41 12.2 5.0 51
rootMargin 51 15 55 38
12.1rootMargin не работает с <iframe>.
51 55 41
12.2rootMargin не работает с <iframe>.
5.0 51
scrollMargin 120 120 Нет 106 Нет 120 Нет 80 Нет 25.0 120
takeRecords 51
15Доступно начиная с Windows Insider Preview Build 14986.
55 38 12.1 51 55 41 12.2 5.0 51
thresholds 52 15 55 39 12.1 52 55 41 12.2 6.0 52
trackVisibility 74 79 Нет 62 Нет 74 Нет 53 Нет 11.0 74
unobserve 51
15Доступно начиная с Windows Insider Preview Build 14986.
55 38 12.1 51 55 41 12.2 5.0 51

См. также

  • Intersection Observer polyfill
  • Измерение времени видимости элемента с помощью Intersection Observer API
  • IntersectionObserver и IntersectionObserverEntry

© 2005–2024 MDN contributors.
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.
https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API