Waypoints — это лёгкая библиотека для отслеживания прокрутки страницы и выполнения функций при достижении определённых элементов. В Angular она используется для создания динамических эффектов при скролле, ленивой подгрузки контента, анимаций и других интерактивных сценариев. Основная задача — корректная интеграция сторонней библиотеки с жизненным циклом компонентов Angular.
Waypoints можно установить через npm:
npm install waypoints
После установки подключение в Angular осуществляется через импорт в компонент или сервис:
import * as Waypoint from 'waypoints/lib/noframework.waypoints';
Важно использовать вариант noframework, так как Angular
не требует jQuery для работы Waypoints.
Для удобного применения в Angular оптимально создавать собственную директиву, которая будет управлять жизненным циклом Waypoints:
import { Directive, ElementRef, Input, OnDestroy, AfterViewInit } from '@angular/core';
import * as Waypoint from 'waypoints/lib/noframework.waypoints';
@Directive({
selector: '[appWaypoint]'
})
export class WaypointDirective implements AfterViewInit, OnDestroy {
@Input() offset: string | number = '50%';
@Input() onEnter: () => void = () => {};
private waypoint!: Waypoint;
constructor(private el: ElementRef) {}
ngAfterViewInit() {
this.waypoint = new Waypoint({
element: this.el.nativeElement,
handler: () => this.onEnter(),
offset: this.offset
});
}
ngOnDestroy() {
if (this.waypoint) {
this.waypoint.destroy();
}
}
}
Пояснения:
AfterViewInit используется для того, чтобы элемент уже
присутствовал в DOM, что критично для Waypoints.OnDestroy позволяет корректно удалять экземпляр
Waypoint и предотвращать утечки памяти.offset задаёт смещение точки активации относительно
верхнего края окна.<div *ngFor="let section of sections"
appWaypoint
[offset]="'75%'"
[onEnter]="() => handleEnter(section)">
{{ section.title }}
</div>
Здесь каждая секция отслеживается отдельно. При достижении точки
активации вызывается функция handleEnter, переданная через
Input.
Waypoints в Angular часто используется вместе с Angular анимациями:
handleEnter(section: any) {
section.active = true; // Используется для добавления класса анимации
}
В шаблоне:
<div [@fadeIn]="section.active ? 'visible' : 'hidden'">
{{ section.content }}
</div>
Это позволяет создавать плавные анимации появления контента при скролле без прямого вмешательства в DOM.
Для динамически загружаемых элементов важно пересоздавать Waypoints
после изменения DOM. В Angular это реализуется через
ngAfterViewChecked:
ngAfterViewChecked() {
this.waypoints.forEach(wp => wp.destroy());
this.initializeWaypoints();
}
private initializeWaypoints() {
this.sections.forEach(section => {
const wp = new Waypoint({
element: document.getElementById(section.id),
handler: () => this.handleEnter(section),
offset: '75%'
});
this.waypoints.push(wp);
});
}
Такой подход гарантирует корректную работу с контентом, который загружается асинхронно, например через HTTP-запросы.
При применении Angular CDK Virtual Scroll необходимо учитывать, что элементы не всегда присутствуют в DOM. В этом случае Waypoints создаётся только для видимых элементов и пересоздаётся при скролле:
cdkVirtualFor="let item of items; let i = index"
(appWaypoint)="onEnter(item)">
Каждое событие прокрутки обрабатывается индивидуально, а Waypoints активируется при появлении элемента в видимой области.
Waypoints поддерживает привязку к окну (window) для
обработки событий скролла глобально:
new Waypoint({
element: document.body,
handler: () => console.log('Scrolled to body'),
offset: '100%'
});
В Angular рекомендуется помещать такую логику в сервис, чтобы использовать её в разных компонентах и централизовать управление событиями скролла.
requestAnimationFrame или IntersectionObserver
вместе с Waypoints для снижения нагрузки на скролл.Waypoints в Angular позволяет гибко управлять скроллом и событиями появления элементов, интегрируясь с шаблонами, директивами и анимациями. Использование директив и сервисов обеспечивает чистую архитектуру и соответствие принципам Angular.