I am developing a breadcrumb bar component in Angular 7 that should dynamically hide and show based on user scrolling behavior.
To achieve this, I created a directive to track the scroll position of the container element. While my code for capturing the scrollTop works well, I'm facing an issue with triggering the HostListener to execute the code.
The main challenge I'm encountering is finding a way to capture scroll events at the page level without attaching a directive to each individual scrolling container. This would limit the flexibility of the component. Is there a method to globally capture scroll events or propagate them to the document level? See below for the HTML Template and Directive code snippet. Ideally, I prefer not to rely on multiple mouse events either.
Any insights on how to approach this problem would be greatly appreciated.
import { Directive, HostListener, Output, EventEmitter, ElementRef } from '@angular/core';
@Directive({
selector: '[scrollListener]'
})
export class ScrollListenerDirective {
previousScrollContainerScrollTop = 0;
@Output() scroll = new EventEmitter<boolean>();
constructor(private el: ElementRef) { }
@HostListener('document:scroll', ['$event'])
onListenerTriggered(): void {
let currentScrollTop: number;
let elementHeight: number;
const scrollContainerScrollTop = this.el.nativeElement.offsetParent.scrollTop;
elementHeight = this.el.nativeElement.offsetHeight;
currentScrollTop = scrollContainerScrollTop;
if (this.previousScrollContainerScrollTop < currentScrollTop && scrollContainerScrollTop > elementHeight + elementHeight) {
this.scroll.emit(true);
} else if (this.previousScrollContainerScrollTop > currentScrollTop && !(scrollContainerScrollTop <= elementHeight)) {
this.scroll.emit(false);
}
this.previousScrollContainerScrollTop = currentScrollTop;
}
}
<ng-container *ngIf="!hide && breadcrumbs && breadcrumbs.length > 1">
<div scrollListener (scroll)="trackScroll($event)" class="breadcrumb-container" [class.scroll-up]="breadcrumbBarHidden" data-id="breadcrumb-navigation">
<div data-id="back-button" class="back-button" (click)="onBackClick()">
<div class="arrow-container">
<mat-icon svgIcon="left"></mat-icon>
</div>
<span>Back</span>
</div>
<div class="crumb-container">
<ng-container *ngFor="let crumb of breadcrumbs; index as i;">
<div class="crumb">
<div class="crumb-label" (click)="onBreadcrumClick(crumb)" [attr.data-id]="'crumb-' + i" [title]="crumb.label">{{crumb.label}}</div>
<div class="chevron-container">
<mat-icon svgIcon="chevron-right"></mat-icon>
</div>
</div>
</ng-container>
</div>
</div>
</ng-container>