一、跳转页面滚动回顶部
当在项目中一个长页面滚动到一定位置后,再跳转(a标签、Vue Router 、React Router)其他长页面时,会导致新加载的页面直接展示为前一个页面滚动的位置,出现这个问题的本质是浏览器的滚动位置缓存机制。
解决方式:手动重置滚动位置
1.React
新增组件 /src/components/ScrollToTop.jsx:
import { useEffect } from 'react';
import { useLocation } from 'react-router-dom';
function ScrollToTop() {
const { pathname } = useLocation();
useEffect(() => {
// 页面跳转时重置滚动位置
window.scrollTo(0, 0);
}, [pathname]);
return null;
}
在App.jsx中使用:
import ScrollToTop from "./components/ScrollToTop.jsx";
...
<App>
<ScrollToTop />
<Routes>...</Routes>
</App>
2.Vue
在 Vue Router 初始化中配置 scrollBehavior:
const router = new VueRouter({
routes: [...],
scrollBehavior(to, from, savedPosition) {
return { x: 0, y: 0 }; // 每次跳转回顶部
}
});
二、点击滚动回顶部
长页面添加滚动回顶部按钮,避免手动操作,提升用户体验。
1.html示例:
通过示例的理解可以将逻辑改写到React、Vue中
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
.container {
position: relative;
width: 100%;
height: 100%;
}
main {
width: 100%;
height: 2000px;
}
#back-to-top {
display: none;
width: 32px;
height: 32px;
cursor: pointer;
position: fixed;
bottom: 20px;
right: 10px;
z-index: 999;
-webkit-animation: floatUp 2s infinite ease-in-out;
animation: floatUp 2s infinite ease-in-out;
}
#back-to-top.show {
display: block;
}
@keyframes floatUp {
0% {
-webkit-transform: translateY(-10px);
transform: translateY(-10px);
}
50% {
-webkit-transform: translateY(10px);
transform: translateY(10px);
}
100% {
-webkit-transform: translateY(-10px);
transform: translateY(-10px);
}
}
</style>
</head>
<body>
<div class="container">
<main>内容</main>
<div id="back-to-top">
<svg
t="1749010463650"
class="icon"
viewBox="0 0 1024 1024"
version="1.1"
xmlns="http://www.w3.org/2000/svg"
p-id="11007"
width="32"
height="32"
>
<path
d="M116.096 596.08h90.87v231.988h42.486V596.08h90.87V553.6H116.095v42.48z m458.537-42.48H462.085c-13.588 0-27.182 5.187-37.545 15.55-10.373 10.367-15.554 23.961-15.554 37.555v168.248c0 13.594 5.181 27.187 15.554 37.555 10.368 10.368 23.962 15.555 37.545 15.555h112.548c13.588 0 27.187-5.187 37.555-15.555s15.55-23.961 15.55-37.555V606.71c0-13.599-5.182-27.187-15.55-37.56-10.368-10.363-23.961-15.55-37.555-15.55z m10.63 221.353c0 2.012-0.549 4.946-3.109 7.516-2.57 2.57-5.509 3.108-7.516 3.108H462.085c-2.007 0-4.936-0.538-7.506-3.108s-3.113-5.504-3.113-7.516V606.71c0-2.012 0.543-4.946 3.113-7.516s5.5-3.113 7.506-3.113h112.548c2.007 0 4.946 0.542 7.506 3.113 2.57 2.57 3.118 5.504 3.118 7.516v168.243h0.005z m307.086-205.804c-10.368-10.357-23.966-15.549-37.555-15.549H709.14v274.463h42.481V707.686h103.173c13.594 0 27.187-5.186 37.555-15.554s15.555-23.962 15.555-37.55v-47.877c0-13.594-5.181-27.182-15.555-37.556z m-26.93 85.433c0 2.007-0.538 4.94-3.109 7.51s-5.509 3.109-7.51 3.109H751.63v-69.12H854.8c2.007 0 4.941 0.542 7.511 3.113s3.108 5.504 3.108 7.516v47.872zM315.97 370.068c55.05-49.602 185.703-167.31 189.758-170.89 5.146-4.541 11.387-3.978 15.304-0.384 2.744 2.52 138.49 124.749 191.227 172.237 8.304 6.994 6.103 20.741-4.317 20.741s-377.85 0.097-384.43 0-14.95-12.416-7.541-21.704z"
p-id="11008"
fill="#1b82f1"
></path>
</svg>
</div>
</div>
<script>
window.addEventListener("scroll", function () {
// 展示返回顶部按钮
if (window.scrollY > 400) {
document.querySelector("#back-to-top").classList.add("show");
} else {
document.querySelector("#back-to-top").classList.remove("show");
}
});
// 添加点击事件
document
.querySelector("#back-to-top")
.addEventListener("click", function () {
window.scrollTo({
top: 0,
behavior: "smooth",
});
});
</script>
</body>
</html>
2.React
新增组件 /src/components/BackToTop.jsx:
import { useState, useEffect } from "react";
export default function BackToTop() {
const [visible, setVisible] = useState(false);
useEffect(() => {
const handleScroll = () => {
setVisible(window.scrollY > 600);
};
window.addEventListener("scroll", handleScroll);
return () => window.removeEventListener("scroll", handleScroll);
}, []);
const scrollToTop = () => {
window.scrollTo({ top: 0, behavior: "smooth" });
};
return visible ? (
<a id="back-to-top" onClick={scrollToTop}>
<svg
t="1749738298463"
class="icon"
viewBox="0 0 1024 1024"
version="1.1"
xmlns="http://www.w3.org/2000/svg"
p-id="4276"
width="32"
height="32"
>
<path
d="M533.333333 512L341.333333 704l29.866667 29.866667 162.133333-162.133334 162.133334 162.133334 29.866666-29.866667-192-192z m0-256L341.333333 448l29.866667 29.866667 162.133333-162.133334 162.133334 162.133334 29.866666-29.866667L533.333333 256z"
fill="#ffffff"
p-id="4277"
></path>
</svg>
</a>
) : null;
}
在style.css中添加按钮样式,该文件记得在main.jsx中引入:
/* back to top button*/
#back-to-top {
font-size: 18px;
font-weight: bold;
width: 40px;
height: 40px;
line-height: 42px;
text-align: center;
background-color: rgba(0, 0, 0, 0.2);
border-radius: 3px;
color: #fff;
position: fixed;
bottom: 20px;
right: 20px;
z-index: 999;
cursor: pointer;
-webkit-box-shadow: 0px 20px 30px 0px rgba(26, 8, 119, 0.24);
-moz-box-shadow: 0px 20px 30px 0px rgba(26, 8, 119, 0.24);
box-shadow: 0px 20px 30px 0px rgba(26, 8, 119, 0.24);
animation: fadeInUp 0.5s linear;
}
@keyframes fadeInUp {
from {
opacity: 0;
-webkit-transform: translate3d(0, 100%, 0);
transform: translate3d(0, 100%, 0);
}
to {
opacity: 1;
-webkit-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
}
}
在App.jsx中使用:
import BackToTop from "./components/BackToTop.jsx";
...
<App>
<Routes>...</Routes>
<BackToTop />
</App>