API адаптеров

Waypoints — это библиотека для отслеживания положения элементов на странице относительно области просмотра (viewport). Основное API работает с Waypoint, который привязывается к конкретному DOM-элементу и вызывается при достижении определённой позиции прокрутки. Однако для расширения функциональности используется API адаптеров, позволяющее интегрировать Waypoints с различными библиотеками и кастомными механизмами прокрутки.


Принцип работы адаптеров

Адаптеры в Waypoints выполняют роль промежуточного слоя между библиотекой и объектами, к которым привязываются события. Они инкапсулируют логику:

  • отслеживания изменения позиции элемента,
  • вычисления границ и размеров,
  • подписки на события прокрутки или изменения DOM.

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

Каждый адаптер должен реализовать три ключевых метода:

  1. viewportHeight() — возвращает высоту видимой области прокрутки.
  2. scrollTop() — возвращает текущую позицию прокрутки.
  3. on(event, handler) / off(event, handler) — добавление и удаление обработчиков событий прокрутки.

Пример адаптера для контейнера с прокруткой:

const CustomAdapter = {
  viewportHeight: function() {
    return document.querySelector('#scroll-container').clientHeight;
  },
  scrollTop: function() {
    return document.querySelector('#scroll-container').scrollTop;
  },
  on: function(event, handler) {
    document.querySelector('#scroll-container').addEventListener('scroll', handler);
  },
  off: function(event, handler) {
    document.querySelector('#scroll-container').removeEventListener('scroll', handler);
  }
};

Подключение адаптера к Waypoints

Чтобы использовать адаптер, его необходимо передать при создании Waypoint через опцию context или через кастомную регистрацию адаптера. Например:

const waypoint = new Waypoint({
  element: document.getElementById('my-element'),
  handler: function(direction) {
    console.log('Waypoint сработал:', direction);
  },
  context: CustomAdapter
});

В этом примере Waypoint использует методы scrollTop() и viewportHeight() адаптера для вычисления момента срабатывания, а on/off для подписки на события прокрутки.


Регистрация собственных адаптеров

Waypoints позволяет регистрировать собственные адаптеры глобально через метод Waypoints.adapters:

Waypoints.adapters.push({
  name: 'customScroll',
  Adapter: CustomAdapter
});

После регистрации можно создавать Waypoints с указанием имени адаптера:

const waypoint = new Waypoint({
  element: document.getElementById('item'),
  handler: function(dir) { console.log(dir); },
  adapter: 'customScroll'
});

Такой подход полезен, если нужно повторно использовать один и тот же механизм прокрутки на нескольких элементах.


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

1. Прокрутка внутри модального окна

Если модальное окно имеет собственную прокрутку:

const modalContainer = document.querySelector('.modal-content');

const modalAdapter = {
  viewportHeight: () => modalContainer.clientHeight,
  scrollTop: () => modalContainer.scrollTop,
  on: (event, handler) => modalContainer.addEventListener('scroll', handler),
  off: (event, handler) => modalContainer.removeEventListener('scroll', handler)
};

new Waypoint({
  element: modalContainer.querySelector('.target'),
  handler: dir => console.log('Waypoint внутри модалки:', dir),
  context: modalAdapter
});

2. Интеграция с библиотекой виртуального скролла

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

const VirtualScrollAdapter = {
  viewportHeight: () => virtualList.clientHeight,
  scrollTop: () => virtualList.scrollTop,
  on: (event, handler) => virtualList.addEventListener('scroll', handler),
  off: (event, handler) => virtualList.removeEventListener('scroll', handler)
};

Особенности и рекомендации

  • Контекст прокрутки: Если элемент находится внутри вложенного контейнера с прокруткой, обязательно использовать адаптер, чтобы Waypoint правильно вычислял позиции.
  • Производительность: Использование кастомных адаптеров позволяет оптимизировать работу с тяжелыми DOM-структурами и виртуальными списками, избегая лишних перерасчетов.
  • Совместимость: Любой адаптер должен возвращать числовые значения для viewportHeight() и scrollTop(), иначе Waypoints не сможет корректно определить момент срабатывания.

API адаптеров в Waypoints открывает гибкость и расширяемость библиотеки, делая её пригодной для сложных интерфейсов с кастомными контейнерами и виртуализированным контентом. Правильная реализация методов адаптера гарантирует стабильное срабатывание Waypoints независимо от структуры страницы или способа прокрутки.