【问题标题】:Scroll to top on browser back button click react在浏览器后退按钮上滚动到顶部单击反应
【发布时间】:2022-11-22 06:01:43
【问题描述】:

每次我的项目中的 URL 更改(以及页面重新加载)时,我都需要滚动到顶部。

一切正常,但浏览器后退按钮出现问题。即使路径名发生变化,页面没有按预期滚动到顶部,它也适用于所有其他情况(页面重新加载和常规链接导航)。

我试图通过为后退按钮创建一个自定义挂钩来解决这个问题,但它并没有按照我想要的方式运行。我还尝试了很多其他的东西,但对于浏览器后退按钮似乎没有任何作用

import { useEffect, useState } from "react";
import { useLocation } from "react-router-dom";

const ScrollToTop = () => {
  const { pathname } = useLocation();

  const useBackButton = () => {
    const [isBack, setIsBack] = useState(false);
    const handleEvent = () => {
      setIsBack(true);
    };
    useEffect(() => {
      window.addEventListener("popstate", handleEvent);
      return () => window.removeEventListener("popstate", handleEvent);
    });
    return isBack;
  };

  const backButton = useBackButton();
  console.log(backButton);

  useEffect(() => {
    window.scrollTo(0, 0);
  }, [pathname, backButton]);

  useEffect(() => {
    window.onbeforeunload = () => {
      window.scrollTo(0, 0);
    };
  }, []);

  return null;
};

export default ScrollToTop;

【问题讨论】:

  • 如果您使用的是单页 React 应用程序,我不希望 onbeforeunload 在页面导航时触发,因为您实际上并没有离开页面。像这样的东西可能有用:Detect Route Change with react-router
  • 你可以创建一个链接并在里面创建一个按钮并放置 href=#
  • 你是对的,但这只是为了页面重新加载。第一个 useEffect 用于导航和后退按钮
  • 通过 const 路径名使用 useLocation 跟踪 url 更改,但由于某种原因,即使在按下浏览器后退按钮时 url 发生更改,也不会触发 scrollTo(0 ,0)

标签: javascript reactjs react-router-dom


【解决方案1】:

我认为 beforeunload 事件在这里不是必需的,但无论如何都会包含它。您可以使用 useNavigationType 挂钩来明确检查 POP 事件类型,而不是为“popstate”事件使用事件侦听器。

笔记:对beforeunload事件使用window.addEventListener,这样你就不会污染/改变window对象。

例子:

import { NavigationType, useLocation, useNavigationType } from "react-router-dom";

const useBackButton = () => {
  const navType = useNavigationType();
  return navType === NavigationType.Pop;
};

const useScrollToTop = () => {
  const { pathname } = useLocation();

  const isPop = useBackButton();

  const scrollToTop = () => window.scrollTo(0, 0);

  useEffect(() => {
    scrollToTop();
  }, [pathname, isPop]);

  useEffect(() => {
    window.addEventListener("beforeunload", scrollToTop);
    return () => {
      window.removeEventListener("beforeunload", scrollToTop);
    };
  }, []);
};

用法:

function App() {
  useScrollToTop();

  return (
    ...
  );
}

【讨论】:

    【解决方案2】:

    这是我使用 React hooks 的解决方案:

    const [showsScrolBtn, setShowScrolBtn] = useState(false);
    
    useEffect(() => {
      const handleButtonVisibility = () => {
        window.pageYOffset > 300 ? setShowScrolBtn(true) : setShowScrolBtn(false);
      };
    
      window.addEventListener("scroll", handleButtonVisibility);
      return () => {
        window.addEventListener("scroll", handleButtonVisibility);
      };
    }, []);
    
    {
      showsScrolBtn && (
        <div
          id="scrolToTop"
          onClick={() => {
            window.scrollTo({
              top: 0,
              left: 0,
              behavior: "smooth",
            });
          }}
          style={{
            position: "fixed",
            bottom: "60px",
            right: "60px",
            color: "gray",
            textAlign: "center",
            cursor: "pointer",
            fontSize: "4em",
            lineHeight: 0,
            textDecoration: "none",
          }}
        >
          Click To Move Top
        </div>
      );
    }
    

    【讨论】:

    • 您的答案可以通过其他支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写出好的答案的信息in the help center
    猜你喜欢
    • 1970-01-01
    • 2018-04-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-15
    • 2013-08-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多