这是一个前端用户体验优化中非常实用的问题:

如何让用户回到上次阅读的位置?

这种功能常见于:

  • 阅读类应用(如小说、文章、PDF页面等)
  • 博客系统、长页面
  • 后台系统列表翻页后返回时保留滚动位置

🎯目标

用户关闭页面或刷新后,自动滚动到上次阅读的位置(滚动位置恢复)


🧩 技术原理

  1. 监听页面滚动位置(scrollTop)
  2. 在用户离开前保存 scrollTop 到 localStorage / sessionStorage
  3. 页面加载后,从本地存储中读取并恢复 scrollTop

✅ 实现方案一:原生 JavaScript 实现

1. 保存滚动位置

window.addEventListener('scroll', () => {
  const scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
  localStorage.setItem('scroll-position', scrollTop);
});

2. 页面加载时还原

window.addEventListener('load', () => {
  const savedPosition = localStorage.getItem('scroll-position');
  if (savedPosition) {
    window.scrollTo(0, parseInt(savedPosition));
  }
});

🚨 注意:需确保页面内容已经加载完成(或延迟)再滚动。


✅ 实现方案二:使用 Vue3 实战(Composition API)

使用 onMounted 和 onUnmounted

import { onMounted, onUnmounted } from 'vue';

export default {
  setup() {
    const saveScroll = () => {
      const top = document.documentElement.scrollTop || document.body.scrollTop;
      localStorage.setItem('vue-scroll-top', top.toString());
    };

    const restoreScroll = () => {
      const saved = localStorage.getItem('vue-scroll-top');
      if (saved) {
        window.scrollTo(0, parseInt(saved));
      }
    };

    onMounted(() => {
      restoreScroll();
      window.addEventListener('scroll', saveScroll);
    });

    onUnmounted(() => {
      window.removeEventListener('scroll', saveScroll);
    });
  }
};

✅ 实现方案三:Router 页面跳转保留滚动(如 Vue Router)

const router = createRouter({
  history: createWebHistory(),
  routes,
  scrollBehavior(to, from, savedPosition) {
    if (savedPosition) {
      return savedPosition;
    } else {
      const scroll = localStorage.getItem('scroll-position');
      return scroll ? { left: 0, top: parseInt(scroll) } : { top: 0 };
    }
  }
});

💬 优化建议

建议
存储方式页面唯一标识 + scrollTop,例如用 URL 为 key
节流处理使用 lodash.throttle 每隔 300ms 存储一次
清理机制页面刷新或退出时清理无用存储或设置过期时间
内容懒加载若内容异步加载过慢,延迟执行 scrollTo(如 setTimeout

📦 第三方封装推荐(可选)

  • VueUse
    useScroll + localStorage 持久化非常方便。const { y } = useScroll(window); watch(y, () => { localStorage.setItem('scrollY', y.value.toString()); }); onMounted(() => { window.scrollTo(0, parseInt(localStorage.getItem('scrollY') || '0')); });

🧠 总结一句话:

离开时存位置,回来时还原它。
只要你能准确监听滚动并持久化,就能让用户回到那个他离开的地方。