在前端项目中实现“用户回到上次阅读位置”的功能,属于提升用户体验的经典技巧,常用于博客文章、长列表、文档阅读等场景。下面从 实现思路、核心代码、进阶优化 三个角度来详细讲解这个功能的实战做法。


🧩 实现思路

  1. 监听滚动位置: 用户滚动时记录 scrollTop
  2. 存储位置数据: 使用 localStorage 或 sessionStorage 存储当前页面的滚动位置。
  3. 页面加载时恢复: 页面加载完毕后读取并设置滚动位置。
  4. 绑定唯一键值: 如果有多篇文章,要用 URL 或 ID 区分存储 key。

🧪 实战代码示例(以 localStorage 为例)

1. 监听并保存滚动位置

window.addEventListener('scroll', () => {
  const scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
  // 使用路径名或唯一文章 ID 作为 key
  localStorage.setItem('scrollPosition_' + location.pathname, scrollTop);
});

2. 页面加载时恢复位置

window.addEventListener('load', () => {
  const savedPosition = localStorage.getItem('scrollPosition_' + location.pathname);
  if (savedPosition) {
    window.scrollTo(0, parseInt(savedPosition));
  }
});

✅ location.pathname 可确保每篇文章记录独立的滚动值。


💡 进阶优化建议

✅ 防抖保存,避免频繁写入

let timeout;
window.addEventListener('scroll', () => {
  clearTimeout(timeout);
  timeout = setTimeout(() => {
    const scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
    localStorage.setItem('scrollPosition_' + location.pathname, scrollTop);
  }, 300); // 300ms 内未再次触发才保存
});

✅ 限制保存条件(如文章页专用)

if (window.location.pathname.startsWith('/article/')) {
  // 执行上述逻辑
}

✅ 使用 sessionStorage 实现临时恢复

  • 如果不需要永久保存,可以改用 sessionStorage
  • 页面关闭就会清除,更适合论坛或文档类。

🚀 Vue / React 实现要点

Vue 示例(可放在 mounted 中)

mounted() {
  const key = 'scrollPosition_' + this.$route.path;
  const saved = localStorage.getItem(key);
  if (saved) {
    this.$nextTick(() => {
      window.scrollTo(0, parseInt(saved));
    });
  }

  window.addEventListener('scroll', () => {
    localStorage.setItem(key, window.scrollY);
  });
}

React 示例(使用 useEffect

useEffect(() => {
  const key = 'scroll_' + window.location.pathname;
  const saved = localStorage.getItem(key);
  if (saved) window.scrollTo(0, parseInt(saved));

  const onScroll = () => localStorage.setItem(key, window.scrollY);
  window.addEventListener('scroll', onScroll);
  return () => window.removeEventListener('scroll', onScroll);
}, []);

📌 注意事项

  • SPA 页面切换不刷新时要确保在路由变化后也能触发保存/恢复逻辑。
  • 内容异步加载(如图片或懒加载组件)时,需在内容完全渲染后再滚动。
  • 移动端兼容性也需测试,有些老旧设备可能对 scrollTo 不响应。

🔗 延伸阅读