Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calling a method when scroll starts

I have a react component that uses scroll events. When the scroll event is called it basically runs the handler as expected. However I need to be able to call a method once when the scroll events begin to fire. I understand the idea of a debounce method which would fire when the scroll stops, but I need to find a way to fire once when scrolling begins. (For sure NO jQuery can be used).

componentDidMount() {
    window.addEventListener('scroll', this.onScroll);

    this.setState({
        // sets some state which is compared in a shouldComponentUpdate
    });
}

componentWillUnmount() {
    window.removeEventListener('scroll', this.onScroll);
}

shouldComponentUpdate(nextProps, nextState) {
    return shallowCompare(this, nextProps, nextState);
}

The handler seen below runs some code:

onScroll() {
    this.scrollTop = document.documentElement.scrollTop;
    this.update();
}

But I need a function that runs once:

scrollStart() {

}

I would love to say I have tried something but unfortunately I have no ideas. Any assist would be greatly appreciated.

like image 595
Aaron Avatar asked Oct 28 '25 07:10

Aaron


1 Answers

There is no real scrolling state in the browser; the scroll event happens, and then it's over.

You could e.g. create a new timeout each time the user scrolls and set your own scrolling state to false if the user hasn't scrolled until the timeout function is run.

Example

class App extends React.Component {
  timeout = null;
  state = { isScrolling: false };

  componentDidMount() {
    window.addEventListener("scroll", this.onScroll);
  }

  componentWillUnmount() {
    window.removeEventListener("scroll", this.onScroll);
  }

  onScroll = () => {
    clearTimeout(this.timeout);
    const { isScrolling } = this.state;

    if (!isScrolling) {
      this.setState({ isScrolling: true });
    }

    this.timeout = setTimeout(() => {
      this.setState({ isScrolling: false });
    }, 200);
  };

  render() {
    return (
      <div
        style={{
          width: 200,
          height: 1000,
          background: this.state.isScrolling ? "green" : "red"
        }}
      />
    );
  }
}

ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

<div id="root"></div>
like image 69
Tholle Avatar answered Oct 31 '25 12:10

Tholle



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!