Множественная инициализация на странице

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


Подготовка HTML

Для множественной инициализации необходимо, чтобы каждый элемент имел уникальный идентификатор или класс:

<header id="main-header">Главное меню</header>
<div class="sub-header">Подшапка с уведомлениями</div>
<nav class="secondary-header">Второстепенное меню</nav>

Важно, чтобы структура DOM позволяла корректно отслеживать scroll events для каждого элемента. Headroom.js использует положение страницы, поэтому каждый элемент будет реагировать на одни и те же события прокрутки.


Создание отдельных экземпляров Headroom

Для каждого элемента создаётся отдельный объект Headroom:

// Основная шапка
const mainHeader = document.getElementById('main-header');
const headroomMain = new Headroom(mainHeader, {
  tolerance: 5,
  offset: 100,
  classes: {
    initial: "headroom",
    pinned: "headroom--pinned",
    unpinned: "headroom--unpinned"
  }
});
headroomMain.init();

// Подшапка с уведомлениями
const subHeader = document.querySelector('.sub-header');
const headroomSub = new Headroom(subHeader, {
  tolerance: 0,
  offset: 50,
  classes: {
    initial: "sub-headroom",
    pinned: "sub-headroom--pinned",
    unpinned: "sub-headroom--unpinned"
  }
});
headroomSub.init();

// Второстепенное меню
const secondaryHeader = document.querySelector('.secondary-header');
const headroomSecondary = new Headroom(secondaryHeader, {
  tolerance: 10,
  offset: 150,
  classes: {
    initial: "secondary-headroom",
    pinned: "secondary-headroom--pinned",
    unpinned: "secondary-headroom--unpinned"
  }
});
headroomSecondary.init();

Каждый экземпляр независим: можно задавать свои параметры offset, tolerance и свои CSS-классы. Это позволяет создавать сложные интерфейсы с разными анимациями для каждой шапки.


Автоматическая инициализация для группы элементов

Если количество элементов заранее неизвестно, удобно использовать цикл:

document.querySelectorAll('.headroom-group').forEach(el => {
  const headroom = new Headroom(el, {
    tolerance: 5,
    offset: 100,
    classes: {
      initial: "headroom",
      pinned: "headroom--pinned",
      unpinned: "headroom--unpinned"
    }
  });
  headroom.init();
});

При таком подходе можно добавить любой элемент с классом headroom-group, и он автоматически получит функционал Headroom.js.


Взаимодействие между экземплярами

В сложных интерфейсах может понадобиться синхронизация:

  • Одновременное скрытие/показ: при прокрутке вниз все шапки скрываются, при прокрутке вверх — показываются.
  • Индивидуальные реакции: разные offset позволяют регулировать момент появления каждого блока.

Пример синхронизации через события:

headroomMain.on('pin', () => {
  headroomSub.pin();
  headroomSecondary.pin();
});

headroomMain.on('unpin', () => {
  headroomSub.unpin();
  headroomSecondary.unpin();
});

События pin и unpin позволяют контролировать цепочку реакций между элементами.


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

При множественной инициализации важно учитывать:

  1. Количество слушателей scroll. Headroom.js использует один глобальный scroll на странице, но каждый экземпляр выполняет обработку. Для десятков элементов лучше объединять их логику или использовать делегирование.
  2. Debounce/Throttle. Если на странице сложная анимация, рекомендуется применять throttling для прокрутки.
  3. CSS-анимации. Использование transform: translateY и transition повышает производительность по сравнению с top или margin.

Настройка разных стратегий поведения

Каждый экземпляр может иметь индивидуальные настройки:

  • offset — число пикселей, после которого начинается скрытие.
  • tolerance — порог для чувствительности к прокрутке.
  • classes — CSS-классы для различных состояний.

Пример разных стратегий:

new Headroom(mainHeader, { offset: 100, tolerance: 5 }).init();
new Headroom(subHeader, { offset: 50, tolerance: 0 }).init();
new Headroom(secondaryHeader, { offset: 150, tolerance: 10 }).init();

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


Рекомендации по CSS

Для корректного отображения множественных шапок:

.headroom {
  position: fixed;
  top: 0;
  width: 100%;
  z-index: 1000;
  transition: transform 0.3s ease-in-out;
}

.sub-headroom {
  position: fixed;
  top: 60px; /* сдвиг от основной шапки */
  width: 100%;
  transition: transform 0.3s ease-in-out;
}

.secondary-headroom {
  position: fixed;
  top: 120px;
  width: 100%;
  transition: transform 0.3s ease-in-out;
}

Правильное использование top и z-index предотвращает наложение элементов и обеспечивает плавные анимации.


Итоговый принцип

Множественная инициализация Headroom.js строится на создании отдельных экземпляров для каждого элемента и, при необходимости, синхронизации их действий через события pin и unpin. Гибкая настройка параметров и правильное использование CSS позволяет создавать сложные динамические интерфейсы с несколькими фиксированными шапками, реагирующими на прокрутку независимо или согласованно.