前端保存并恢复用户上次阅读位置的几种做法
在阅读类、资讯类、博客类网站里,'下次打开还能接着看'算不上炫技,但体验差别很明显。实现这件事,常见思路就三种:直接记 scrollY,用 Intersection Observer 记录章节位置,或者干脆把位置写进 URL 的 hash。

思路先放清楚
目标其实只有两个:
- 用户滚动时,把当前位置记下来。
- 页面再次打开时,能回到那个位置。
实现上可以用这些能力配合:
scroll事件监听localStorage本地存储requestAnimationFrame做节流Intersection Observer观察章节进入视口- Vue3 组件化封装(如果项目本来就是 Vue)
直接记录 scrollTop
最直觉的做法,就是在滚动时记录 window.scrollY,存到 localStorage,页面加载后再 scrollTo 回去。
这套方案上手最快,适合内容结构简单的页面。问题也很直接:scroll 触发太频繁,尤其是长页面,硬写成'每次滚动都存一次'会有点吵。用固定时间间隔去节流也能跑,但手感通常不如 requestAnimationFrame 稳。
// 用于保存最新滚动位置
let lastKnownScrollY = 0;
// 用于控制 requestAnimationFrame
let ticking = false;
// 监听滚动事件
window.addEventListener('scroll', () => {
lastKnownScrollY = window.scrollY;
// 防止过度频繁存储,使用 requestAnimationFrame 节流
if (!ticking) {
window.requestAnimationFrame(() => {
// 将滚动位置保存在 localStorage 中
localStorage.setItem('scrollPosition', lastKnownScrollY);
ticking = ;
});
ticking = ;
}
});
.(, {
savedPosition = .();
(savedPosition !== ) {
.(, (savedPosition));
}
});


