Существует несколько способов достижения этого, но, поскольку вы уже используете @angular/material
, вы можете воспользоваться @angular/cdk
и ScrollDispatchModule
(см. документы ).
Это позволяет вам легко и просто наблюдать за событиями прокрутки для зарегистрированных элементов вне NgZone, что означает, что это будет иметь небольшое влияние на производительность.
См. Пример stackblitz: https://stackblitz.com/edit/angular-npdbtp
Сначала вам нужно импортировать ScrollDispatchModule
и зарегистрировать провайдера для ScrollDispatcher
:
import {ScrollDispatchModule, ScrollDispatcher} from '@angular/cdk/scrolling';
@NgModule({
imports: [
(other imports)
ScrollDispatchModule
],
providers: [ScrollDispatcher]
})
export class AppModule {}
Затем в вашем шаблоне вы можете пометить элемент html с помощью * Директива 1020 *. Это автоматически зарегистрирует его в ScrollDispatcher
. Вы также можете привязать стиль компонента (например, непрозрачность) к свойству, определенному в вашем компоненте:
<div class="scroll-wrapper" cdkScrollable>
<mat-toolbar class="sticky-toolbar" [style.opacity]="opacity">My App</mat-toolbar>
<div>content</div>
</div>
Вы можете сделать элемент html липким, используя display: sticky
вместе с top: 0
:
.sticky-toolbar {
position: sticky;
top: 0px;
}
Затем вам нужно будет вставить ScrollDispatcher
и NgZone
в ваш компонент и определить свойство непрозрачности:
opacity = 1;
constructor(
private scrollDispatcher: ScrollDispatcher,
private zone: NgZone
) {}
Затем вы можете подписаться на прокручиваемые события ScrollDispatcher. Они испускаются для всех зарегистрированных компонентов. Вы также можете зарегистрироваться для прокрутки событий одного элемента - обратитесь к документации, если это необходимо.
ngOnInit(): void {
this.scrollDispatcher.scrolled().subscribe((event: CdkScrollable) => {
const scroll = event.measureScrollOffset("top");
let newOpacity = this.opacity;
if (scroll > 0) {
newOpacity = 0.75;
} else {
newOpacity = 1;
}
if (newOpacity !== this.opacity) {
this.zone.run(() => {
this.opacity = newOpacity;
});
}
});
}
* ScrollDispatcher
работает за пределами NgZone, что означает, что он не будет запускать обнаружение изменений во всем приложении. Это позволяет повысить производительность, и поэтому мы также внедряем NgZone и запускаем изменение свойств внутри зоны - это вызывает правильное обнаружение изменений вдоль дерева компонентов.