简体   繁体   中英

Trying to detect scroll direction in react

I want to move some html elements in the direction of the scroll direction. I've added a scroll event listener which updates the state of the scroll position. I also have a useRef that stores the previous value of the scroll position every time it changes. I compare the previous value and the current scroll position. If the scroll position is greater, then that means the scroll direction is down. Otherwise, the scroll direction is up. However, this code doesn't work. The condition always seems to read false. How can I detect the scroll direction using react.

import './App.css';

function App() {

  const [scrollPosition, setScrollPosition]=useState(window.scrollY);
  const prevScrollPosition=useRef(0);

  useEffect(()=>{
    window.addEventListener('scroll',((e)=>{
      setScrollPosition(window.scrollY);
    }))
  },[])

  useEffect(()=>{
    prevScrollPosition.current=scrollPosition;

    
    
    if(scrollPosition>prevScrollPosition.current){
      document.querySelector(".scalp").style.top=(document.querySelector(".scalp").offsetTop+7)+"px";
      document.querySelector(".brain").style.top=(document.querySelector(".brain").offsetTop+3)+"px";

    }else{
      document.querySelector(".scalp").style.top=(document.querySelector(".scalp").offsetTop-7)+"px";
      document.querySelector(".brain").style.top=(document.querySelector(".brain").offsetTop-3)+"px";
    }

  },[scrollPosition])

  
  
  return (
    <div className="App">
      
      <video className="cloudsVideo" autoplay playsinline autoplay loop muted src="Pexels Videos 3723.mp4" muted loop autoplay alt="clouds"></video>
      <video className="spaceVideo" autoplay playsinline autoplay loop muted src="pexels-ahnaf-piash-5747525.mp4" muted loop autoplay alt="space"></video>
      <img className="scalp" src="scalp.png"/>
      <img className="brain" src="Brain-PNG-Photos.png"/>
      <img className="head" src="head.png"/>

      <h1>{scrollPosition}</h1>
      <h1>{prevScrollPosition.current}</h1>
      <h1>{scrollPosition-prevScrollPosition.current}</h1>
      

      
    </div>
  );
}

export default App;

I think something like this will work for you:

import { useState, useRef, useEffect, useCallback } from 'react';

export const useScrollDirection = () => {
  const [scrollPosition, setScrollPosition] = useState<number>(0);
  const [isScrollingUp, setIsScrollingUp] = useState<boolean>(false);
  const [isScrollingDown, setIsScrollingDown] = useState<boolean>(false);
  const prevScrollPosition = useRef<number>(0);

  const handleScroll = useCallback(() => {
    prevScrollPosition.current = scrollPosition;
    const position = window.pageYOffset;
    setScrollPosition(position);
  }, [scrollPosition]);

  useEffect(() => {
    window.addEventListener('scroll', handleScroll, { passive: true });

    if (scrollPosition - prevScrollPosition.current > 0) {
      setIsScrollingUp(false);
      setIsScrollingDown(true);
    } else if (scrollPosition - prevScrollPosition.current < 0) {
      setIsScrollingDown(false);
      setIsScrollingUp(true);
    }
    return () => {
      window.removeEventListener('scroll', handleScroll);
    };
  }, [handleScroll, scrollPosition]);

  return { isScrollingDown, isScrollingUp };
};

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM