Sam
Sam

Reputation: 68

Stop scrolling Event after function typescript

Is it possible to prevent any further scrolling event after a function.

I would like to generate an effect, where you can scroll down a site, and if you are at the bottom of this site, you can scroll further but then a new site will appear from the left - as you would scroll to the left. this new page appears with an animation, so i don't want to trigger it directly if the bottom of the page is reached.

I am setting a timeout, as far as you reach the bottom:

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

and the animation will only trigger, if this.unitBottom==true. So you scroll to the bottom and then after 1 second you can scroll again and the next site will appear from the left.

My Problem: If you're scrolling as me on a mac, your scroll event will go on even if you don't touch the touchpad. This generates normally a smooth scroll on casual pages, but here it could be that you scroll to the bottom, the setTimeout triggers and your scroll event still triggers after that second.

So: Is it possible to stop the ongoing scroll event on a mac after you lift up your fingers (or even on any other computers, i don't know those mechanics)

This may be an unsolvable problem, because normally you can't change the computers input, but maybe some of you would have some idea.

Sincerly, Sam

EDIT

I think all of the people, who answered my question didn't get the point, that i do need the scrollevent and can't simply disable it. The only thing that helped was the comment unter my question.

Upvotes: 6

Views: 6732

Answers (4)

Mikkel Christensen
Mikkel Christensen

Reputation: 2817

I took a different approach to most people here. The easiest way to stop scrolling is utilizing css to set the overflow to hidden.

With this in mind I created a directive which utilizes the angular @HostListener to listen for scroll events. Once the element which the directive is attached has its bottom scrolled into view, we disable overflow-y on the body element.

First we inject the services we need

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

We'll utilize the Renderer2 to apply the style to the body element, and we need a reference to the ViewContainer of the directive to know whenever what the directive is applied to has its bottom region inside of the viewport.

We setup the @HostListenerto accomplish this:

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

This practically does what we need. From here you can initiate whatever other logic you need such as an animation transition, etcetera.

expanded example
I added a few more details to the directive, such as an input binding for an EventEmitter to unfreeze the scrolling, and a flag for only triggering once. The full directive listing is as follows:

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");
  }
}

You can find a stackblitz example here: https://stackblitz.com/edit/angular-ivy-64dpad

Upvotes: 0

Cristian Sarghe
Cristian Sarghe

Reputation: 790

How I would do it is listening to the scroll event until the bottom of the page is reached.

When it is reached, attach the extra scroll event that triggers the animation. This means that it will not get triggered when you reach the bottom of the page the first time, but when you try to scroll again after reaching it.

Upvotes: 0

Ritchie
Ritchie

Reputation: 562

You can listen to the scroll event by using addEventListener. In this function you can monitor the window.scrollY position. Once you reach a certain Y position you can temporarily disable the scrollbar by adding overflow: hidden; to the document (or your container element).

Example:

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

Upvotes: 1

nikoswsn
nikoswsn

Reputation: 192

You can't disable scrolling events. You can do however disable the actions that cause scrolling. In my opinion instead of using multiple event listeners as mentioned here I would suggest the following solution: where the user scrolls but you manipulate the event in order to remain at the same position and when you want to reEnable the scrolling you override the window.onscroll with a blank function

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() {}; 
} 

Upvotes: 0

Related Questions