Доступ к адаптерам

Waypoints — это библиотека для работы с событиями скролла, позволяющая реагировать на появление элементов в видимой области окна браузера. Центральным понятием является Waypoint, объект, который привязывается к конкретному DOM-элементу и отслеживает его положение относительно окна или родительского контейнера. Важной частью работы Waypoints является адаптер, обеспечивающий совместимость с различными средами и упрощающий работу с DOM и событиями.


Адаптеры в Waypoints

Адаптер — это интерфейс между Waypoints и конкретным способом доступа к DOM. Он скрывает различия между jQuery, Zepto или чистым JavaScript и позволяет Waypoints работать с любым из них без изменения внутренней логики. В Waypoints по умолчанию используются следующие адаптеры:

  • jQueryAdapter — для проектов, использующих jQuery.
  • ZeptoAdapter — для проектов на Zepto.
  • NativeAdapter — для чистого JavaScript без сторонних библиотек.

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


Методы адаптеров

Все адаптеры поддерживают несколько ключевых методов, необходимых для работы Waypoints:

  1. offset() Получение позиции элемента относительно документа. Принимает на вход элемент и возвращает объект с координатами top и left.

  2. scrollTop() Получение текущей вертикальной позиции скролла контейнера. Используется для вычисления, достиг ли элемент нужной точки.

  3. scrollLeft() Получение текущей горизонтальной позиции скролла.

  4. height() и width() Определение размеров элемента или контейнера, что важно для вычисления триггеров waypoint’ов.

  5. bind() и unbind() Привязка и снятие обработчиков событий скролла и изменения размеров. Адаптер гарантирует корректную работу с различными механизмами событий в jQuery, Zepto и нативном JS.

  6. each() Итерация по коллекции элементов для создания множества waypoint’ов одновременно.

  7. extend() Объединение объектов с опциями, позволяющее легко наследовать или переопределять параметры waypoint’а.


Регистрация и использование адаптеров

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

  • Добавлять новые адаптеры

    Waypoint.adapters.push({
        name: 'CustomAdapter',
        adapter: CustomAdapter
    });
  • Выбирать используемый адаптер для конкретного waypoint

    var waypoint = new Waypoint({
        element: document.getElementById('myElement'),
        handler: function(direction) {
            console.log('Waypoint достигнут:', direction);
        },
        context: window,
        adapter: 'NativeAdapter'
    });
  • Переопределять методы существующих адаптеров для кастомизации поведения.


Контекст и адаптеры

Каждый waypoint создаётся в определённом контексте — контейнере, относительно которого вычисляется позиция элемента. Адаптер отвечает за корректный расчёт позиции элемента и скролла внутри контекста, обеспечивая точное срабатывание waypoint’а. При использовании кастомного контекста важно удостовериться, что выбранный адаптер умеет работать с этим контейнером.

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

var waypoint = new Waypoint({
    element: document.querySelector('.section'),
    handler: function(dir) {
        console.log('Секция достигнута', dir);
    },
    context: document.querySelector('.scroll-container'),
    adapter: 'NativeAdapter'
});

Особенности кастомных адаптеров

Создание собственного адаптера может потребоваться, если стандартные jQuery, Zepto или NativeAdapter не удовлетворяют требованиям проекта. Основные шаги:

  1. Определение методов интерфейса: offset, scrollTop, scrollLeft, height, width, bind, unbind, each, extend.
  2. Обеспечение совместимости с API Waypoints. Методы должны возвращать объекты и значения в том формате, который ожидает библиотека.
  3. Регистрация адаптера через Waypoint.adapters.push().

Пример минимального кастомного адаптера:

var CustomAdapter = {
    offset: function(el) {
        var rect = el.getBoundingClientRect();
        return { top: rect.top + window.scrollY, left: rect.left + window.scrollX };
    },
    scrollTop: function() {
        return window.scrollY || document.documentElement.scrollTop;
    },
    scrollLeft: function() {
        return window.scrollX || document.documentElement.scrollLeft;
    },
    height: function(el) {
        return el ? el.offsetHeight : window.innerHeight;
    },
    width: function(el) {
        return el ? el.offsetWidth : window.innerWidth;
    },
    bind: function(el, event, handler) {
        el.addEventListener(event, handler);
    },
    unbind: function(el, event, handler) {
        el.removeEventListener(event, handler);
    },
    each: function(collection, callback) {
        Array.prototype.forEach.call(collection, callback);
    },
    extend: function(dest, src) {
        return Object.assign(dest, src);
    }
};

Waypoint.adapters.push({ name: 'CustomAdapter', adapter: CustomAdapter });

Практические советы по использованию адаптеров

  • Совместимость с библиотеками: Если проект использует jQuery, лучше использовать jQueryAdapter — это минимизирует ошибки в работе с DOM.
  • Производительность: NativeAdapter работает быстрее, так как не зависит от сторонних библиотек и использует нативные методы.
  • Кастомные контейнеры: При скролле внутри блока с overflow: scroll убедиться, что адаптер корректно вычисляет позиции относительно этого блока.
  • Множественные waypoint’ы: Для больших страниц и сложных интерфейсов рекомендуется создавать waypoint’ы с одним и тем же адаптером для унифицированного поведения.