Search code examples
javascriptangulareventsscrollmousewheel

How to fire only once Mousewheel scroll


I am trying on scroll with mousewheel to do some actions. I want no matter how fast or how many times you scroll the wheel, it to count as "one". Now if you scroll fast it will count more times.

https://stackblitz.com/edit/angular-yttk3y


Solution

  • Have a timer to restrict the scroll for certain duration and retain the scroll direction to detect change in scroll direction.

    import { Directive, HostListener } from '@angular/core';
    import { timer } from 'rxjs';
    @Directive({
      selector: '[appMouseScroll]'
    })
    export class MouseScrollDirective {
      Ttimer;
      isMouseWheelInRogress;
      scrollUp;
    
      @HostListener('wheel', ['$event']) onMouseScroll(e) {
    
        if (!this.isMouseWheelInRogress || (!this.scrollUp && e.deltaY < 0 || this.scrollUp && e.deltaY > 0)) {
          if (this.Ttimer) {
            this.Ttimer.unsubscribe();
          }
          this.Ttimer = timer(500).subscribe(() => {
            this.isMouseWheelInRogress = false;
          });
    
          if (e.deltaY < 0) {
            this.scrollUp = true;
            console.log('scrolling up');
          } else if (e.deltaY > 0) {
            this.scrollUp = false;
            console.log('scrolling down');
          }
        }
        this.isMouseWheelInRogress = true;
      }
    }