简体   繁体   English

在浏览器后退按钮上滚动到顶部单击反应

[英]Scroll to top on browser back button click react

I need to scroll to the top every time the URL changes in my project (and on page reload).每次 URL 在我的项目中发生变化时(以及页面重新加载时),我都需要滚动到顶部。

Everything is working but I am having a problem with the browser back button.一切正常,但浏览器后退按钮出现问题。 Even if the pathname changes the page doesn't scroll to the top as it should, it works on all other cases (page reload and regular link navigation).即使路径名发生变化,页面没有按预期滚动到顶部,它也适用于所有其他情况(页面重新加载和常规链接导航)。

I tried to counter that by creating a custom hook just for the back button, but it's not behaving how I want.我试图通过为后退按钮创建一个自定义挂钩来解决这个问题,但它并没有按照我想要的方式运行。 I also tried a bunch of other things, but nothing seems to work as for the browser back button我还尝试了很多其他的东西,但对于浏览器后退按钮似乎没有任何作用

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;

I don't think the beforeunload event is necessary here, but will include it anyway.我认为这里不需要beforeunload事件,但无论如何都会包含它。 Instead of using an event listener for the "popstate" event you can use the useNavigationType hook to expressly check for a POP event type.您可以使用useNavigationType挂钩来明确检查 POP 事件类型,而不是为“popstate”事件使用事件侦听器。

Note : Use window.addEventListener for the beforeunload event so you don't pollute/mutate the window object.注意:将window.addEventListener用于beforeunload事件,这样您就不会污染/改变window object。

Example:例子:

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);
    };
  }, []);
};

Usage:用法:

function App() {
  useScrollToTop();

  return (
    ...
  );
}

编辑滚动到顶部的浏览器后退按钮单击反应

Here is my solution using React hooks:这是我使用 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>
  );
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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