Manny
Manny

Reputation: 156

How to identify which element scroll is being used?

I have a component in react, in which on click of a button ~ I display a drop down of a menu options.

Both menu overflow and browser screen overflow is enabled.

My requirement is that when the user is scrolling the menu. No changes required. However, if the menu is open and user tries to scroll the browser scroll - the menu should close.

WHAT AM I DOING TO ACHIEVE THIS?

  private handleMenu = (condition)? debounce(() => this.closeAllMenus(), 500, 
   {
    leading: true
   }) : debounce((event) => {}, 0, {});

Here, I am facing problems in finding the "condition"

condition should equal to get the instance when user is scrolling the browser scroll.

If true, I will close the menu dropdown for an interval. If false, (i.e. user is actually using scroll of the menu) - do nothing.

This is being called like this: -

private addEventListeners() {
    document.addEventListener("scroll", this.handleMenu, true);   
  }

  private removeEventListeners() {
    document.removeEventListener("scroll", this.handleMenu, true);
  }

FOLLOWING ARE THE CONDITIONS I HAVE TRIED "condition":-

  1. window.scrollY - However, this does not tell me whether the user is currently scrolling it or not.

    It will only tell me the Y co-ordinate.

    How do I get to know which scroll is being used by currently.

  2. document.activeElement.mouseleave - but that would just tell me that mouse pointer is not on the menu. But not that scroll of the browser is being used.

    How do I get to know which scroll is being used currently ?

  3. disable the browser scroll using document.body.style.overflow = "hidden". However, this is not a recommended approach.

This image has a button in the bottom -

https://ibb.co/552TSnJ

On click of the button, a menu will open as shown in image -

https://ibb.co/BgsmYSm

How do I get to know if currently my browser scroll is being scrolled.

  private handleMenu = (condition)? debounce(() => this.closeAllMenus(), 500, 
   {
    leading: true
   }) : debounce((event) => {}, 0, {});

My requirement is just to close the menu when user tries to scroll the browser scroll and keep it open if user is trying to scroll the menu element scroll.

EDIT: -

As suggested by one of the answers below, I changed my method to the following code: -

private handleMenu = (event: MouseEvent) => {
    event.preventDefault();
    window.onscroll = () => {
      this.closeAllMenus();
    }
  }

Upvotes: 2

Views: 858

Answers (2)

Ben Swindells
Ben Swindells

Reputation: 269

Try using the class function ComponentDidMount() this will mount your code when components loads into the window.

constructor(props)
{
    super(props);
    this.state = ({
        scrollYnow: 0,
    });
    this.trackScrolling = this.trackScrolling.bind(this);
}
trackScrolling = () => {
    this.setState({scrollYnow: window.scrollY})
    console.log(this.state.scrollYnow);
}
componentDidMount() {

        document.addEventListener('scroll', this.trackScrolling);

}

This will update your function as the user scrolls, detects the scrollY but this can be changed with any scroll JS attribute hope this helps :)

Upvotes: 2

Gunnar Thoreson
Gunnar Thoreson

Reputation: 313

try make use of the 'scroll' event using

window.addEventListener('scroll', yourFunction());

as per documentation, depending on the content of the given function you might want to throttle it for performance sake. so you could for example use a timeout that prevents its executing for a given time in between calls.

but using this event you know when the user is scrolling and just use a callback to close the given window.

to register to scroll events on an element you can make use of the 'onscroll' attribute.

Upvotes: 2

Related Questions