Router
Kendini kullanmak, tutarlı tarayıcı deneyimini sürdürmek için tamamen üstesinden gelemediğiniz sorunlara neden olacaktır. Bence en iyi yöntem, sadece bir özel kullanmak directive
ve tıklama üzerine kaydırma sıfırlamak için izin vermektir. Bununla ilgili iyi bir şey, url
tıklattığınızla aynı konumdaysanız, sayfanın da en üste geri kaymasıdır. Bu normal web siteleriyle tutarlıdır. Temel directive
şöyle görünebilir:
import {Directive, HostListener} from '@angular/core';
@Directive({
selector: '[linkToTop]'
})
export class LinkToTopDirective {
@HostListener('click')
onClick(): void {
window.scrollTo(0, 0);
}
}
Aşağıdaki kullanımla:
<a routerLink="/" linkToTop></a>
Bu çoğu kullanım durumu için yeterli olacaktır, ancak bundan kaynaklanabilecek birkaç sorun hayal edebiliyorum:
universal
Kullanımı nedeniyle çalışmıyorwindow
- Her tıklama ile tetiklendiği için değişiklik algılamaya küçük hız etkisi
- Bu yönergeyi devre dışı bırakmanın bir yolu yok
Bu sorunların üstesinden gelmek aslında oldukça kolaydır:
@Directive({
selector: '[linkToTop]'
})
export class LinkToTopDirective implements OnInit, OnDestroy {
@Input()
set linkToTop(active: string | boolean) {
this.active = typeof active === 'string' ? active.length === 0 : active;
}
private active: boolean = true;
private onClick: EventListener = (event: MouseEvent) => {
if (this.active) {
window.scrollTo(0, 0);
}
};
constructor(@Inject(PLATFORM_ID) private readonly platformId: Object,
private readonly elementRef: ElementRef,
private readonly ngZone: NgZone
) {}
ngOnDestroy(): void {
if (isPlatformBrowser(this.platformId)) {
this.elementRef.nativeElement.removeEventListener('click', this.onClick, false);
}
}
ngOnInit(): void {
if (isPlatformBrowser(this.platformId)) {
this.ngZone.runOutsideAngular(() =>
this.elementRef.nativeElement.addEventListener('click', this.onClick, false)
);
}
}
}
Bu, çoğu kullanım senaryosunu, temel olanla aynı kullanımla, etkinleştirmek / devre dışı bırakmak avantajını dikkate alır:
<a routerLink="/" linkToTop></a> <!-- always active -->
<a routerLink="/" [linkToTop]="isActive"> <!-- active when `isActive` is true -->
reklam vermek istemiyorsanız okumayın
Tarayıcının passive
olayları destekleyip desteklemediğini kontrol etmek için başka bir iyileştirme yapılabilir . Bu, kodu biraz daha karmaşıklaştıracaktır ve tüm bunları özel yönergelerinizde / şablonlarınızda uygulamak istiyorsanız biraz belirsizdir. Bu yüzden bu sorunları çözmek için kullanabileceğiniz küçük bir kütüphane yazdım . Yukarıdaki işlevle aynı işleve sahip olmak ve eklenen passive
etkinlikle birlikte , ng-event-options
kitaplığı kullanıyorsanız yönergelerinizi değiştirebilirsiniz . Mantık click.pnb
dinleyicinin içindedir :
@Directive({
selector: '[linkToTop]'
})
export class LinkToTopDirective {
@Input()
set linkToTop(active: string|boolean) {
this.active = typeof active === 'string' ? active.length === 0 : active;
}
private active: boolean = true;
@HostListener('click.pnb')
onClick(): void {
if (this.active) {
window.scrollTo(0, 0);
}
}
}
RouterModule.forRoot(appRoutes, { scrollPositionRestoration: 'enabled' })