Создание собственных плагинов

Headroom.js предоставляет гибкую систему плагинов, позволяющую расширять стандартное поведение библиотеки. Плагин — это объект, содержащий набор методов жизненного цикла, которые вызываются в определённые моменты работы Headroom. Основные этапы взаимодействия плагина с Headroom:

  • init — вызывается один раз при инициализации Headroom, используется для начальной настройки.
  • destroy — вызывается при удалении экземпляра Headroom, позволяет очищать ресурсы или удалять слушатели событий.
  • onPin / onUnpin — методы, вызываемые при изменении состояния шапки (прикреплена / откреплена).
  • onTop / onNotTop — вызываются при достижении страницы верхней позиции или при её покидании.
  • onBottom / onNotBottom — аналогично, реагируют на нижнюю границу страницы.

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


Создание простого плагина

Для начала создаётся объект с методами плагина. Например, плагин для добавления CSS-класса при закреплении шапки:

const AddClassOnPin = {
  init(headroom) {
    this.headroom = headroom;
  },
  onPin() {
    this.headroom.elem.classList.add('pinned');
  },
  onUnpin() {
    this.headroom.elem.classList.remove('pinned');
  }
};

Здесь:

  • init сохраняет ссылку на экземпляр Headroom.
  • onPin и onUnpin изменяют класс элемента.
  • Можно добавлять любые методы или свойства для хранения состояния плагина.

Подключение плагина к Headroom

Подключение осуществляется через массив options при создании экземпляра:

const header = document.querySelector('header');
const headroom = new Headroom(header, {
  tolerance: 5,
  offset: 100,
  classes: {
    pinned: 'header-pinned',
    unpinned: 'header-unpinned'
  },
  onPin() { console.log('Pinned'); },
  plugins: [AddClassOnPin]
});

headroom.init();
  • plugins принимает массив объектов, каждый из которых реализует методы плагина.
  • Плагины интегрируются в основной цикл Headroom и получают уведомления о событиях.

Работа с параметрами плагина

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

function AddClassPlugin(className) {
  return {
    init(headroom) {
      this.headroom = headroom;
      this.className = className;
    },
    onPin() {
      this.headroom.elem.classList.add(this.className);
    },
    onUnpin() {
      this.headroom.elem.classList.remove(this.className);
    }
  };
}

const headroom = new Headroom(header, {
  plugins: [AddClassPlugin('visible')]
});

headroom.init();

Использование фабрики позволяет создавать несколько плагинов с разными настройками, не дублируя код.


Поддержка событий и подписок

Плагины могут добавлять собственные обработчики событий для расширенной функциональности:

const ScrollLogger = {
  init(headroom) {
    this.handleScroll = () => console.log(window.scrollY);
    window.addEventListener('scroll', this.handleScroll);
  },
  destroy() {
    window.removeEventListener('scroll', this.handleScroll);
  }
};

const headroom = new Headroom(header, { plugins: [ScrollLogger] });
headroom.init();
  • Метод destroy критичен для предотвращения утечек памяти.
  • Плагины могут регистрировать слушатели на window, document или внутренние события Headroom.

Наследование и композиция плагинов

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

class BaseLoggerPlugin {
  init(headroom) { this.headroom = headroom; }
  log(message) { console.log(`[Headroom] ${message}`); }
}

class AdvancedLogger extends BaseLoggerPlugin {
  onPin() { this.log('Header pinned'); }
  onUnpin() { this.log('Header unpinned'); }
}
  • Наследование упрощает повторное использование функционала.
  • Любой плагин может комбинироваться с другими, поддерживая модульность.

Советы по проектированию плагинов

  • Всегда реализовывать destroy, если создаются слушатели событий или таймеры.
  • Использовать init для подготовки состояния и хранения ссылки на Headroom.
  • Минимизировать прямое вмешательство в DOM, лучше работать через классы и стили.
  • Поддерживать конфигурируемость через фабрики или параметры конструктора.
  • Следить за производительностью: плагины должны быть лёгкими и не вызывать лишних перерисовок при скролле.

Пример комплексного плагина: анимация шапки

function AnimatedHeader(animationClass) {
  return {
    init(headroom) { this.headroom = headroom; this.animationClass = animationClass; },
    onPin() { this.headroom.elem.classList.add(this.animationClass); },
    onUnpin() { this.headroom.elem.classList.remove(this.animationClass); },
    onTop() { this.headroom.elem.style.opacity = '1'; },
    onNotTop() { this.headroom.elem.style.opacity = '0.9'; },
    destroy() { this.headroom.elem.classList.remove(this.animationClass); }
  };
}

const headroom = new Headroom(header, {
  plugins: [AnimatedHeader('slide-down')]
});
headroom.init();
  • Плагин сочетает CSS-анимацию с изменением прозрачности.
  • Методы жизненного цикла полностью управляют состоянием шапки.
  • Конфигурируемый класс анимации позволяет повторное использование.

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