reactjs 我做了一个React钩子来根据滚动位置、滚动方向和滚动速度控制NavBar的可见性,如何优化这一点?

vvppvyoh  于 2023-05-22  发布在  React
关注(0)|答案(1)|浏览(126)

这里是React钩子。我想模仿这个网站上的行为:Humboldt forum
基本上,导航栏是粘性的,向下滚动时隐藏,快速向上滚动时重新出现,总是在顶部可见。

const useScrollSpeed = (navHeight: number, maxScrollSpeed: number) => {

  const [lastScrollTime, setLastScrollTime] = useState(new Date().getTime());
  const [currentScrollPos, setCurrentScrollPos] = useState(0)
  const [prevScrollPos, setPrevScrollPos] = useState(0);
  const [visible, setVisible] = useState(true);

  const handleScroll = () => {
    const distance = Math.abs(currentScrollPos - prevScrollPos);
    const scrollSpeed = distance / (new Date().getTime() - lastScrollTime);

  
      if (currentScrollPos > prevScrollPos) {
        setVisible(false);
      } else {
        if (scrollSpeed > maxScrollSpeed) {
          setVisible(true);
        }
      }

    setPrevScrollPos(currentScrollPos);
    setLastScrollTime(new Date().getTime());
  };

  if (typeof window !== "undefined") {
    useEffect(() => {
      setCurrentScrollPos(window.scrollY)
  
      if (currentScrollPos < navHeight) {
        setVisible(true);
      } 
      window.addEventListener("scroll", handleScroll);
      return () => window.removeEventListener("scroll", handleScroll);
    }, [window.scrollY]);
  }
  

  return visible;
};
export default useScrollSpeed;

我如何进一步优化它以提高性能?

3htmauhk

3htmauhk1#

以下是我的ES-Linted版本:

const useScrollSpeed = (navHeight: number, maxScrollSpeed: number) => {

  const [lastScrollTime, setLastScrollTime] = useState(new Date().getTime());
  const [currentScrollPos, setCurrentScrollPos] = useState(0)
  const [prevScrollPos, setPrevScrollPos] = useState(0);
  const [visible, setVisible] = useState(true);

  const handleScroll = useCallback(() => {
    const distance = Math.abs(currentScrollPos - prevScrollPos);
    const scrollSpeed = distance / (new Date().getTime() - lastScrollTime);

  
      if (currentScrollPos > prevScrollPos) {
        setVisible(false);
      } else {
        if (scrollSpeed > maxScrollSpeed) {
          setVisible(true);
        }
      }

    setPrevScrollPos(currentScrollPos);
    setLastScrollTime(new Date().getTime());
  }, [currentScrollPos, prevScrollPos, lastScrollTime, setVisible, maxScrollSpeed])

  useEffect(() => {
    setCurrentScrollPos(window.scrollY)

    if (currentScrollPos < navHeight) {
      setVisible(true);
    } 
    window.addEventListener("scroll", handleScroll);
    return () => window.removeEventListener("scroll", handleScroll);
  }, [currentScrollPos, handleScroll, navHeight]);

  

  return visible;
};
export default useScrollSpeed;

相关问题