Intersection Observer API: основные параметры и настройки - Smart-Frontend

Intersection Observer API: основные параметры и настройки

Intersection Observer API: основные параметры и настройки


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

Опции и настройки Intersection Observer API

Интерфейс Intersection Observer API предоставляет возможность применять несколько опций и настроек. Например, имеется возможность передачи массива параметров (все они необязательны) в качестве второго аргумента конструктора new IntersectionObserver():

  • root — родительский элемент для наблюдения за целевыми элементами, расположенными внутри него. По умолчанию — это область просмотра, но им также может быть и любой другой прокручиваемый элемент.
  • rootMargin — маргины, используемые для корневого элемента при обнаружении пересечения. Этот параметр работает аналогично свойству margin в CSS, и по умолчанию имеет значение 0px 0px 0px 0px. Установка положительного числа приведет к тому, что наблюдаемые элементы будут иметь значение isIntersecting, равное true, прежде чем они появятся в области видимости (или другом родительском элементе — root).
  • threshold — параметр Intersection Observer API, отвечающий за то, какая часть элемента должна находиться в области видимости (или в root элементе), чтобы он считаться видимым. Значение 0 (установлено по умолчанию) означает, что учитывается даже один пиксель, значение 1 — что все пиксели элемента должны быть видны. Для срабатывания метода при появлении элемента на 25% достаточно установить пороговое значение в 0,25. Можно передать одно число или массив чисел.

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

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

 

// Ленивая загрузка текста
function loadText (entries, obs) {
    entries.forEach(function (entry) {
// Если наблюдаемый элемент находится за пределами зоны видимости, то ничего не происходит
        if (!entry.isIntersecting) return;
// Отключаем «наблюдателя»
        obs.unobserve(entry.target);
// Выводим в консоль сообщение, когда элемент войдет в зону видимости
        console.log('Элемент в зоне видимости');
// Добавляем в него текст
        entry.target.textContent += 'Элемент в зоне видимости';
    });
}

// Задаем опции для «наблюдателя»
let options = {
    rootMargin: '50px'
};

// Создаем новый «наблюдатель»
let observer = new IntersectionObserver(loadText, options);
// Указываем элемент для «наблюдения»
let app = document.querySelector('.element');
// Прикрепляем «наблюдателя» к элементу
observer.observe(app);

Наблюдение за несколькими элементами

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

При наблюдении за несколькими элементами сразу массив entries может (но не обязательно) содержать несколько элементов.

Если element_1 и element_2 не расположены рядом друг с другом, один может покинуть область просмотра, когда второй еще в нее не вошел. В этой ситуации тот, который из нее выйдет, сохраняется в массиве entries со значением isIntersecting равным false. А второй будет иметь значение true.

// Создаем новый «наблюдатель»
let observer = new IntersectionObserver(function (entries) {
    console.log(entries);
    entries.forEach(function (entry) {
        console.log(entry.target);
        console.log(entry.isIntersecting);
    });
});

// Указываем элементы для «наблюдения»
let el_1 = document.querySelector('.element_1');
let el_2 = document.querySelector('.element_2');

// Прикрепляем элементы к «наблюдателя»
observer.observe(el_1);
observer.observe(el_2);

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

Альтернативный шаблон — один наблюдатель на элемент

Подключение нескольких элементов к одному Intersection Observer API может привести к некоторым неудобствам. Это в первую очередь актуально при командной работе над одним проектом.

В качестве альтернативы можно использовать один «наблюдатель» для каждого элемента. При таком подходе полезно использовать именованную функцию обратного вызова и внешнюю переменную для параметров.

Еще одним способом является создание вспомогательной функции, которая создает новый конструктор IntersectionObserver(). Она активирует «наблюдение» за элементом и вернет «наблюдателя» (observer).

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

/**
Создаем intersection observer
elem - элемент для «наблюдения»
callback - callback-функция
options - объект опций, если они необходимы (необязательный параметр)
*/
function createIntersectionObserver (elem, callback, options) {
    let observer = new IntersectionObserver(callback, options || {});
    observer.observe(elem);
    return observer;
}

/**
Выводим в консоль элемент, если он входит в зону видимости
entries - массив «наблюдаемых» элементов
 */
function log (entries) {
    let [entry] = entries;
    console.log(entries);
    console.log(entry.target);
    console.log(entry.isIntersecting);
}

// Задаем опции для «наблюдателя»
let options = {
    rootMargin: '50px'
};

// Указываем элементы для «наблюдения»
let el_1 = document.querySelector('.element_1');
let el_2 = document.querySelector('.element_2');

/**
Создаем «наблюдателя» для каждого элемента
Для первого указываем опции
*/
createIntersectionObserver(el_1, log, options);

// Второй использует ту же самую callback-функцию, но без опций
createIntersectionObserver(el_2, log);

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

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

Кроссбраузерность

Учитывая, что Internet Explorer не поддерживает Intersection Observer API, а в Safari и FireFox Android имеются некоторые проблемы, без полифила не обойтись.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *