【问题标题】:Stop scrolling Event after function typescript函数打字稿后停止滚动事件
【发布时间】:2020-06-24 18:08:14
【问题描述】:

是否可以在函数之后阻止任何进一步的滚动事件。

我想生成一个效果,您可以在其中向下滚动一个站点,如果您在该站点的底部,您可以进一步滚动,但随后会从左侧出现一个新站点 - 就像您滚动到左边。这个新页面会出现一个动画,所以如果到达页面底部我不想直接触发它。

我正在设置一个超时,直到你到达底部:

this.timeoutUnitBottom = setTimeout(() => this.unitBottom = true, 1000);

只有在 this.unitBottom==true 时才会触发动画。因此,您滚动到底部,然后在 1 秒后您可以再次滚动,下一个站点将从左侧出现。

我的问题:如果您在 Mac 上像我一样滚动,即使您不触摸触摸板,您的滚动事件也会继续。这通常会在休闲页面上生成平滑滚动,但在这里可能是您滚动到底部,setTimeout 触发并且您的滚动事件在那一秒之后仍然触发。

所以:抬起手指后是否可以在 Mac 上停止正在进行的滚动事件(甚至在任何其他计算机上,我都不知道这些机制)

这可能是一个无法解决的问题,因为通常您无法更改计算机输入,但也许你们中的一些人会有一些想法。

真诚地, 山姆

编辑

我认为所有回答我问题的人都没有明白这一点,即我确实需要滚动事件并且不能简单地禁用它。唯一有帮助的是我的问题下的评论。

【问题讨论】:

标签: angular typescript macos scroll


【解决方案1】:

您可以使用addEventListener 监听滚动事件。在此功能中,您可以监控window.scrollY 位置。到达某个 Y 位置后,您可以通过将 overflow: hidden; 添加到文档(或您的容器元素)来暂时禁用滚动条。

例子:

window.addEventListener('scroll', function(e) {
  if (window.scrollY >= 200) {
    document.documentElement.style.overflow = 'hidden';
  }
});

【讨论】:

    【解决方案2】:

    您不能禁用滚动事件。但是,您可以禁用导致滚动的操作。在我看来,而不是像here 提到的那样使用多个事件侦听器,我建议使用以下解决方案:用户滚动但您操纵事件以保持在同一位置以及当您想要重新启用滚动时覆盖窗口.onscroll 带有一个空白函数

    disableScroll() { 
        // Get the current page scroll position 
        scrollTop = window.pageYOffset || document.documentElement.scrollTop; 
        scrollLeft = window.pageXOffset || document.documentElement.scrollLeft, 
      
            // if any scroll is attempted, set this to the previous value 
            window.onscroll = function() { 
                window.scrollTo(scrollLeft, scrollTop); 
            }; 
    } 
      
    enableScroll() { 
        window.onscroll = function() {}; 
    } 
    

    【讨论】:

      【解决方案3】:

      我会怎么做是监听滚动事件,直到到达页面底部。

      到达时,附加触发动画的额外滚动事件。这意味着它不会在您第一次到达页面底部时触发,而是在您到达该页面后再次尝试滚动时触发。

      【讨论】:

        【解决方案4】:

        我对这里的大多数人采取了不同的方法。停止滚动最简单的方法是利用 css 将溢出设置为隐藏。

        考虑到这一点,我创建了一个指令,它利用角度 @HostListener 来监听滚动事件。一旦附加指令的元素的底部滚动到视图中,我们就禁用 body 元素上的 overflow-y。

        首先我们注入我们需要的服务

        constructor(private render: Renderer2, private container: ViewContainerRef) {}

        我们将利用 Renderer2 将样式应用到 body 元素,并且我们需要对该指令的 ViewContainer 的引用,以了解何时应用指令的对象的底部区域位于视口内。

        我们设置 @HostListener 来完成此操作:

          @HostListener("window:scroll")
          scrollEvent() {
            const bounds = this.container.element.nativeElement.getBoundingClientRect();
            if (bounds.bottom <= window.innerHeight) {
              this.render.setStyle(document.body, "overflowY", "hidden");
            }
          }
        

        这实际上可以满足我们的需要。从这里您可以启动您需要的任何其他逻辑,例如动画转换等。

        扩展示例
        我在指令中添加了更多细节,例如用于解除滚动冻结的 EventEmitter 的输入绑定,以及仅触发一次的标志。完整的指令列表如下:

        import { Directive, HostListener, Renderer2, ViewContainerRef, EventEmitter, Input, OnInit } from "@angular/core";
        
        @Directive({
          selector: "[appScroll]"
        })
        export class ScrollDirective implements OnInit {
        
          @Input() fireOnce: boolean;
          @Input() enableScroll: EventEmitter<any>;
          hasFired: boolean;
        
          @HostListener("window:scroll")
          scrollEvent() {
            const bounds = this.container.element.nativeElement.getBoundingClientRect();
            if (bounds.bottom <= window.innerHeight && !this.hasFired) {
              this.render.setStyle(document.body, "overflowY", "hidden");
              this.hasFired = this.fireOnce;
            }
          }
          constructor(private render: Renderer2, private container: ViewContainerRef) {
            this.hasFired = false;
          }
        
          ngOnInit() {
            if (this.enableScroll) {
              this.enableScroll.subscribe(r => this.removeNoSCrollClass());
            }
          }
        
          removeNoSCrollClass() {
            this.render.removeStyle(document.body, "overflowY");
          }
        }
        

        您可以在此处找到 stackblitz 示例:https://stackblitz.com/edit/angular-ivy-64dpad

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2013-03-29
          • 1970-01-01
          • 1970-01-01
          • 2018-11-15
          • 1970-01-01
          • 2020-07-14
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多