【问题标题】:How to get on scroll events?如何参加滚动事件?
【发布时间】:2017-05-09 08:49:05
【问题描述】:

我需要从带有溢出的 div 获取滚动事件:在我的 Angular 2 应用中滚动。

似乎onscroll event 不适用于 Angular 2。

我怎样才能做到这一点?

【问题讨论】:

  • 通常您可以应用 onclick、onsubmit 等事件。在 Angular 中,等价物通常只是从事件名称中删除“on”并添加 ()。例如(点击)、(提交)等... :)

标签: html css angular typescript scrollbar


【解决方案1】:
// @HostListener('scroll', ['$event']) // for scroll events of the current element
@HostListener('window:scroll', ['$event']) // for window scroll events
onScroll(event) {
  ...
}

<div (scroll)="onScroll($event)"></div>

【讨论】:

  • (scroll)="onScroll($event)" 很好地解决了我的问题。你知道元素的 onresize 是否有等效的绑定?
  • 不,浏览器不提供调整元素大小的事件,仅用于调整窗口大小 ('window:resize')。您可以实现ngDoCheck() 并在那里轮询大小。虽然这可能很昂贵,因此如果您可以依赖不太频繁的事件来使用此类事件来轮询大小,那将是首选。
  • @GünterZöchbauer 你能从事件中看出卷轴的方向吗?那是没有检查和比较 div scrollY 值与以前的值?
  • developer.mozilla.org/en-US/docs/Web/Events/scroll 列出了事件提供的信息,其中不包括任何有关方向的信息。
  • 另外,这个在Angular 6中工作 --> stackoverflow.com/a/42547136/621951
【解决方案2】:

您可以使用@HostListener 装饰器。适用于 Angular 4 及更高版本。

import { HostListener } from '@angular/core';

@HostListener("window:scroll", []) onWindowScroll() {
    // do some stuff here when the window is scrolled
    const verticalOffset = window.pageYOffset 
          || document.documentElement.scrollTop 
          || document.body.scrollTop || 0;
}

【讨论】:

  • 如何为一组 or 语句设置一个常量?
  • @SirPapilonius 第一个不是假的(0 或未定义等)将用作值。
  • @StackUnderflow 啊,当然,这是有道理的。没想到。聪明!
  • HostListener 会导致此处提到的过度更改检测。 github.com/angular/angular/issues/16986 我确实看到了使用主机监听器对性能的影响,不是另一种方式吗?
【解决方案3】:

对于 Angular 4,工作解决方案是在组件内部进行

@HostListener('window:scroll', ['$event']) onScrollEvent($event){
  console.log($event);
  console.log("scrolling");
} 

【讨论】:

  • 你好,我刚刚在我的组件中使用了你的代码,最后我添加了一个 (scroll)="onScrollEvent($event)" 但我不起作用。
  • (scroll)="onScrollEvent($event)" 不起作用,但我的代码目前正在使用角度版本 4.0.0,它会触发滚动事件
  • 这个工作正常,不需要在 HTML 中添加 (scroll)="onScrollEvent($event) 这个。
  • HostListener 会导致此处提到的过度更改检测。 github.com/angular/angular/issues/16986 我确实看到了使用主机监听器对性能的影响,不是另一种方式吗?
【解决方案4】:

收听window:scroll 事件以进行窗口/文档级滚动和元素的scroll 事件以进行元素级滚动。

窗口:滚动

@HostListener('window:scroll', ['$event'])
onWindowScroll($event) {

}

<div (window:scroll)="onWindowScroll($event)">

滚动

@HostListener('scroll', ['$event'])
onElementScroll($event) {

}

<div (scroll)="onElementScroll($event)">

如果宿主元素本身不可滚动,@HostListener('scroll', ['$event']) 将不起作用。

示例

【讨论】:

  • 记得添加import:import { HostListener } from '@angular/core';
  • &lt;div (window:scroll)="onWindowScroll($event)"&gt;,清晰,简单,对我来说就像一个魅力。谢谢老哥!
  • HostListener 会导致此处提到的过度更改检测。 github.com/angular/angular/issues/16986我确实看到了使用主机监听器对性能的影响,不是另一种方式吗?
【解决方案5】:

要捕获滚动事件并查看调用了哪个滚动事件,您必须使用主机侦听器来观察滚动行为,然后在主机侦听器下面的函数中检测到这个东西。

currentPosition = window.pageYOffset;
@HostListener('window:scroll', ['$event.target']) // for window scroll events
scroll(e) {
  let scroll = e.scrollingElement.scrollTop;
  console.log("this is the scroll position", scroll)
  if (scroll > this.currentPosition) {
    console.log("scrollDown");
  } else {
    console.log("scrollUp");
  }
  this.currentPosition = scroll;
}

【讨论】:

    【解决方案6】:

    替代@HostListener 并在元素上滚动输出我建议使用RxJS 中的fromEvent,因为您可以将它与filter()distinctUntilChanges() 链接起来,并且可以轻松地跳过洪水冗余事件(和变更检测)。

    这是一个简单的例子:

    // {static: true} can be omitted if you don't need this element/listener in ngOnInit
    @ViewChild('elementId', {static: true}) el: ElementRef;
    
    // ...
    
    fromEvent(this.el.nativeElement, 'scroll')
      .pipe(
        // Is elementId scrolled for more than 50 from top?
        map((e: Event) => (e.srcElement as Element).scrollTop > 50),
        // Dispatch change only if result from map above is different from previous result
        distinctUntilChanged());
    

    【讨论】:

      【解决方案7】:

      检查此 URL 上提及的多个示例。

      我会推荐方法3,

      https://itnext.io/4-ways-to-listen-to-page-scrolling-for-dynamic-ui-in-angular-ft-rxjs-5a83f91ee487

          @Component({
              selector       : 'ngx-root',
              templateUrl    : './app.component.html',
              styleUrls      : [ './app.component.scss' ],
              changeDetection: ChangeDetectionStrategy.OnPush
          })
          export class AppComponent implements OnDestroy {
              
              destroy = new Subject();
              
                  destroy$ = this.destroy.asObservable();
              
              constructor() {
                  fromEvent(window, 'scroll').pipe(takeUntil(this.destroy$))
                      .subscribe((e: Event) => console.log(this.getYPosition(e)));
                  }
              
                  getYPosition(): number {
                  return (e.target as Element).scrollTop;
                  }
      
              ngOnDestroy(): void {
                  this.destroy.next();
              }
              
          }
      

      不过方法4还不错。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-01-12
        • 2018-05-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-02-10
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多