Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angular/32.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何处理Angular 4中的窗口滚动事件?_Javascript_Angular_Typescript - Fatal编程技术网

Javascript 如何处理Angular 4中的窗口滚动事件?

Javascript 如何处理Angular 4中的窗口滚动事件?,javascript,angular,typescript,Javascript,Angular,Typescript,我似乎无法捕获窗口滚动事件。 在几个网站上,我发现了类似的代码: @HostListener("window:scroll", []) onWindowScroll() { console.log("Scrolling!"); } 这些代码片段通常来自版本2。在Angular 4.2.2中,这似乎不起作用(不再?)。例如,如果我将“window:scroll”替换为“window:touchmove”,则touchmove事件处理得很好 有人知道我错过了什么吗?多谢各位 您的文档可能没有滚

我似乎无法捕获窗口滚动事件。 在几个网站上,我发现了类似的代码:

@HostListener("window:scroll", [])
onWindowScroll() {
  console.log("Scrolling!");
}
这些代码片段通常来自版本2。在Angular 4.2.2中,这似乎不起作用(不再?)。例如,如果我将“window:scroll”替换为“window:touchmove”,则touchmove事件处理得很好


有人知道我错过了什么吗?多谢各位

您的
文档可能没有滚动,但其中有一个
div
。如果从
文档
调用滚动事件,则滚动事件只会出现在
窗口
。另外,如果您从
文档
中捕获事件并调用类似于
停止播放
的调用,您将不会在
窗口
中收到事件

如果您想捕获应用程序中的所有滚动事件,这些事件也将来自微小的可滚动容器,则必须使用默认的
addEventListener
方法,并将
useCapture
设置为
true

这将在事件进入
DOM
而不是冒泡阶段时触发事件。不幸的是,坦率地说,angular没有提供传递事件侦听器选项的选项,因此您必须使用
addEventListener

export class WindowScrollDirective {

    ngOnInit() {
        window.addEventListener('scroll', this.scroll, true); //third parameter
    }

    ngOnDestroy() {
        window.removeEventListener('scroll', this.scroll, true);
    }

    scroll = (event): void => {
      //handle your scroll here
      //notice the 'odd' function assignment to a class field
      //this is used to be able to remove the event listener
    };

}
现在这还不是它的全部,因为所有主要的浏览器(除了IE和Edge,显然)都实现了新的
addEventListener
spec,这使得可以将对象作为对象传递

使用此对象,您可以将事件侦听器标记为
被动
。对于引发大量时间的事件,建议执行此操作,这可能会干扰UI性能,如滚动事件。要实现此功能,应首先检查当前浏览器是否支持此功能。在mozilla.org上,他们发布了一个方法
被动支持
,您可以使用该方法检查浏览器支持。但是,只有在确定不使用
event.preventDefault()

在我向您展示如何做到这一点之前,您可以考虑另一个性能特性。为了防止更改检测运行(每次区域内发生异步事件时都会调用
DoCheck
。如事件触发),您应该在区域外运行事件侦听器,并且只有在确实需要时才输入它。苏,让我们把这些结合起来:

export class WindowScrollDirective {

    private eventOptions: boolean|{capture?: boolean, passive?: boolean};

    constructor(private ngZone: NgZone) {}

    ngOnInit() {            
        if (passiveSupported()) { //use the implementation on mozilla
            this.eventOptions = {
                capture: true,
                passive: true
            };
        } else {
            this.eventOptions = true;
        }
        this.ngZone.runOutsideAngular(() => {
            window.addEventListener('scroll', this.scroll, <any>this.eventOptions);
        });
    }

    ngOnDestroy() {
        window.removeEventListener('scroll', this.scroll, <any>this.eventOptions);
        //unfortunately the compiler doesn't know yet about this object, so cast to any
    }

    scroll = (): void => {
        if (somethingMajorHasHappenedTimeToTellAngular) {
           this.ngZone.run(() => {
               this.tellAngular();
           });
        }
    };   
}
导出类WindowScrollDirective{
私有事件选项:布尔{capture?:布尔,被动?:布尔};
构造函数(专用ngZone:ngZone){}
ngOnInit(){
如果(被动式支持()){//请在mozilla上使用该实现
this.eventOptions={
捕捉:没错,
被动:对
};
}否则{
this.eventOptions=true;
}
此.ngZone.runOutsideAngular(()=>{
window.addEventListener('scroll',this.scroll,this.eventOptions);
});
}
恩贡德斯特罗(){
window.removeEventListener('scroll',this.scroll,this.eventOptions);
//不幸的是,编译器还不知道这个对象,所以转换到任何
}
滚动=():无效=>{
如果(某个重大事件发生在伦敦时间){
此.ngZone.run(()=>{
这个;
});
}
};   
}

我还不能发表评论@PierreDuc你的答案是正确的,除非@Robert说文档不会滚动。我稍微修改了您的答案,以使用侦听器发送的事件,然后监视源元素

 ngOnInit() {
    window.addEventListener('scroll', this.scrollEvent, true);
  }

  ngOnDestroy() {
    window.removeEventListener('scroll', this.scrollEvent, true);
  }

  scrollEvent = (event: any): void => {
    const n = event.srcElement.scrollingElement.scrollTop;
  }

如果碰巧使用了角度材质,可以执行以下操作:

import { ScrollDispatchModule } from '@angular/cdk/scrolling';
在Ts中:

import { ScrollDispatcher } from '@angular/cdk/scrolling';

  constructor(private scrollDispatcher: ScrollDispatcher) {    
    this.scrollDispatcher.scrolled().subscribe(x => console.log('I am scrolling'));
  }
在模板中:

<div cdkScrollable>
  <div *ngFor="let one of manyToScrollThru">
    {{one}}
  </div>
</div>

{{1}}

参考资料:

在angular 8中,实现此代码,在我的例子中,使用scroll。。。 您的模板:

<div class="level" (scroll)="scrolling($event)"  [ngClass]="{'level-trans': scroll}">
<!-- your template -->
</div>
你的css

.level{
    width: 100%;
    height: 57px;
    box-shadow: 0 0 5px 0 rgba(0, 0,0,0.7);
    background: transparent;
    display: flex;
    position: fixed;
    top: 0;
    z-index: 5;
    transition: .8s all ease;
}
.level-trans{
    background: whitesmoke;
}

以防万一,我想在一个没有滚动条的元素上捕捉轮子的动作

所以,我需要的是:

@HostListener('mousewheel', ['$event']) 
onMousewheel(event) {
     console.log(event)
}

我不知道我是否错过了什么。。。因为我也有同样的问题(即使在今天[2021]的网上也找不到任何答案),但我只是试着用“body”替换“window”,它工作得很好(代码少得多)

代码段(在我的示例中,已添加到我的navbar组件):

@HostListener('body:scroll',['$event']))
public onScrollingEvent():void{
log(“当前滚动”);
this.navbarClass=['nav','addshadow'];
}

希望同一地点的其他人也能发现这一点,这会让他们的生活更轻松

非常感谢,这似乎像预期的那样有效!我认为问题确实在于文档本身在我的情况下没有滚动。@Robert我用其他信息更新了我的答案:)第二个代码块中侦听器内的内容是否与拦截事件相关?此外,我如何确定卷轴的方向?这正是我在回答中所说的:)@mkb它不是过时的。它非常有用。它只是不支持使用本机事件选项。感谢您包含
事件
参数。如果没有它,被接受的答案是没有用的。你知道我如何从函数中访问组件的范围吗?非常感谢,这似乎对我来说是有效的!在这种情况下,如何获得滚动方向和偏移量。发出的事件似乎为空。@SaurabhTiwari-请参阅中的:
measureScrollOffset
。可以以可观察的方式与Rxjs
成对组合,查看滚动的方向。也许有更直接的方法,但这是一个解决方案。我明白你的意思。但是
scrollDispatcher
上不支持
measureScrollOffset
方法。它仅在cdk scrollable上受支持
@HostListener('mousewheel', ['$event']) 
onMousewheel(event) {
     console.log(event)
}