[英]How can I capture any scroll event from an element on the page using HostListener (Angular 7)?
I am making a reusable breadcrumb bar component in Angular 7. I want it to hide once the page has been scrolled a bit and then reappear when the user scrolls back up.我正在 Angular 7 中制作一个可重复使用的面包屑栏组件。我希望它在页面滚动一点后隐藏,然后在用户向上滚动时重新出现。
I made a directive to attach to the bar itself that references the offsetParent to capture the scrollTop of the container that actually scrolls.我做了一个指令来附加到引用 offsetParent 的栏本身以捕获实际滚动的容器的 scrollTop。 All of that code works, but I'm not sure how to trigger the HostListener to actually run the code.
所有这些代码都有效,但我不确定如何触发 HostListener 来实际运行代码。
I am going to preface this question with the fact that I really don't want to have to attach a directive to each container that scrolls as that will make the component less flexible.我将用这样一个事实作为这个问题的开头,即我真的不想为每个滚动的容器附加一个指令,因为这会使组件的灵活性降低。 How can I capture any scroll event on a page?
如何捕获页面上的任何滚动事件? Code snippet below is the HTML Template and the Directive.
下面的代码片段是 HTML 模板和指令。 I'd rather not use a bunch of mouse events either.
我也不想使用一堆鼠标事件。 There surely has to be someway to capture scroll events or at least make them bubble up to the document level.
肯定必须有某种方法来捕获滚动事件,或者至少让它们冒泡到文档级别。
Thanks in Advance.提前致谢。
import { Directive, HostListener, Output, EventEmitter, ElementRef, Inject } 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>
I figured it out.我想到了。 I ended up using a pure Javascript event listener that fires my function using the event emitter.
我最终使用了一个纯 Javascript 事件侦听器,它使用事件发射器触发我的 function。 Worked great.
工作得很好。
import { Directive, HostListener, Output, EventEmitter, ElementRef, Inject } from '@angular/core'; @Directive({ selector: '[ScrollListener]' }) export class ScrollListenerDirective { previousScrollContainerScrollTop = 0; @Output() scroll = new EventEmitter<boolean>(); constructor(private el: ElementRef) { document.addEventListener('scroll', (event) => { this.onListenerTriggered(event); }, true); // This is so we can use a UseCapture event listener. Document scrolls do not bubble back up to the document level } onListenerTriggered(event): 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; } }
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.