Использование в Angular

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

Установка и подключение

Установка производится через npm:

npm install headroom.js --save

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

import Headroom from "headroom.js";

Если используется Angular CLI, важно удостовериться, что headroom.js доступен для сборки. Можно добавить путь к библиотеке в angular.json в разделе scripts, если требуется глобальное подключение:

"scripts": [
  "node_modules/headroom.js/dist/headroom.min.js"
]

Создание директивы для Angular

Для удобной интеграции лучше использовать кастомную директиву, которая инициализирует Headroom на элементе.

import { Directive, ElementRef, AfterViewInit, OnDestroy } from '@angular/core';
import Headroom from 'headroom.js';

@Directive({
  selector: '[appHeadroom]'
})
export class HeadroomDirective implements AfterViewInit, OnDestroy {
  private headroom: Headroom;

  constructor(private el: ElementRef) {}

  ngAfterViewInit(): void {
    this.headroom = new Headroom(this.el.nativeElement, {
      tolerance: 5,
      offset: 50,
      classes: {
        initial: 'headroom',
        pinned: 'headroom--pinned',
        unpinned: 'headroom--unpinned',
        top: 'headroom--top',
        notTop: 'headroom--not-top',
        bottom: 'headroom--bottom',
        notBottom: 'headroom--not-bottom',
      }
    });
    this.headroom.init();
  }

  ngOnDestroy(): void {
    this.headroom.destroy();
  }
}

Ключевые моменты директивы:

  • ElementRef используется для прямого доступа к DOM-элементу.
  • Инициализация в ngAfterViewInit обеспечивает наличие элемента в DOM перед созданием Headroom.
  • ngOnDestroy отвечает за очистку ресурсов, предотвращая утечки памяти.
  • classes позволяет полностью кастомизировать CSS-классы для различных состояний шапки.

Использование директивы в шаблоне

После создания директивы её можно подключить к любому элементу шапки:

<header appHeadroom class="main-header">
  <nav>
    <!-- Меню навигации -->
  </nav>
</header>

Это позволит шапке реагировать на прокрутку: скрываться при скролле вниз и появляться при скролле вверх.

Настройка параметров

Headroom.js предоставляет несколько важных опций:

  • tolerance — количество пикселей, на которое нужно прокрутить, чтобы триггернуть скрытие или показ шапки. Может быть числом или объектом {up: number, down: number}.
  • offset — смещение в пикселях от верха страницы, после которого шапка начинает реагировать на прокрутку.
  • classes — объект с кастомными классами для состояний (pinned, unpinned, top, notTop и т.д.).
  • scroller — элемент, за скроллом которого будет следить Headroom (по умолчанию window).

Пример настройки с разными значениями для прокрутки вверх и вниз:

this.headroom = new Headroom(this.el.nativeElement, {
  tolerance: { up: 10, down: 5 },
  offset: 100
});

Стилизация с помощью CSS

Для работы Headroom необходимо определить стили для классов состояний:

.headroom {
  transition: transform 0.3s ease-in-out;
  will-change: transform;
}

.headroom--pinned {
  transform: translateY(0);
}

.headroom--unpinned {
  transform: translateY(-100%);
}

Использование CSS-переходов обеспечивает плавное скрытие и появление шапки.

Управление через сервис

В крупных приложениях рекомендуется создавать сервис для управления состоянием Headroom из разных компонентов. Пример сервиса:

import { Injectable } from '@angular/core';
import Headroom from 'headroom.js';

@Injectable({
  providedIn: 'root'
})
export class HeadroomService {
  private instances = new Map<HTMLElement, Headroom>();

  init(element: HTMLElement, options?: any): void {
    if (this.instances.has(element)) return;
    const headroom = new Headroom(element, options);
    headroom.init();
    this.instances.set(element, headroom);
  }

  destroy(element: HTMLElement): void {
    const instance = this.instances.get(element);
    if (instance) {
      instance.destroy();
      this.instances.delete(element);
    }
  }
}

Сервис позволяет централизованно контролировать несколько элементов, упрощая поддержку и масштабирование.

Обработка событий

Headroom.js предоставляет коллбеки для событий:

  • onPin — вызывается при закреплении шапки.
  • onUnpin — при скрытии шапки.
  • onTop — при достижении верхней позиции.
  • onNotTop — когда элемент покидает верхнюю позицию.

Пример подключения коллбеков:

this.headroom = new Headroom(this.el.nativeElement, {
  onPin: () => console.log('Pinned'),
  onUnpin: () => console.log('Unpinned')
});

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

Интеграция с Angular Material

Для проектов с Angular Material шапку можно обернуть в <mat-toolbar> и применять директиву Headroom, сохраняя адаптивность и Material-стили:

<mat-toolbar appHeadroom color="primary">
  <span>Логотип</span>
  <span class="spacer"></span>
  <button mat-button>Войти</button>
</mat-toolbar>

Такое сочетание обеспечивает плавное поведение шапки с современным UI.

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

Для больших приложений рекомендуется:

  • Ограничивать количество элементов с Headroom на странице.
  • Использовать requestAnimationFrame для кастомных событий при высокочастотной прокрутке.
  • Кэшировать DOM-ссылки и минимизировать пересчёт стилей в коллбеках.

Эти меры значительно сокращают нагрузку на браузер и делают анимацию шапки плавной даже на мобильных устройствах.