要让用户回到上次阅读的位置,通常有以下几种实现方法:

1. 使用 LocalStorage 或 SessionStorage

LocalStorage 和 SessionStorage 都可以用来在浏览器中存储数据,LocalStorage 会在浏览器会话结束后依然保留,而 SessionStorage 在页面会话结束后会清空。

在这个场景中,使用 LocalStorage 存储用户的阅读位置比较合适,因其可以跨会话保留数据。具体步骤如下:

  • 保存位置:当用户滚动页面时,记录当前滚动位置。
  • 恢复位置:当用户重新打开页面时,读取保存的滚动位置,并滚动到相应的位置。

示例代码:

// 保存滚动位置
window.addEventListener('scroll', () => {
    localStorage.setItem('scrollPosition', window.scrollY);
});

// 页面加载时恢复滚动位置
window.addEventListener('load', () => {
    const savedPosition = localStorage.getItem('scrollPosition');
    if (savedPosition) {
        window.scrollTo(0, savedPosition);
    }
});

这段代码会在用户滚动页面时,实时保存滚动位置,然后在页面加载时恢复滚动位置。

2. 使用 Cookie

如果你希望跨多个会话保存用户的滚动位置,可以选择使用 Cookie。与 LocalStorage 类似,Cookie 也可以用来存储小量数据。

  • 保存位置:每次用户滚动时将位置保存到 Cookie 中。
  • 恢复位置:页面加载时从 Cookie 中读取位置并滚动到相应的位置。

示例代码:

// 保存滚动位置到 cookie
window.addEventListener('scroll', () => {
    document.cookie = `scrollPosition=${window.scrollY}; path=/; max-age=31536000`; // 存储1年
});

// 页面加载时恢复滚动位置
window.addEventListener('load', () => {
    const cookies = document.cookie.split('; ');
    const scrollCookie = cookies.find(cookie => cookie.startsWith('scrollPosition='));
    if (scrollCookie) {
        const savedPosition = scrollCookie.split('=')[1];
        window.scrollTo(0, parseInt(savedPosition, 10));
    }
});

3. 使用 URL Hash 或 Query 参数

如果你不想使用浏览器的存储机制,可以考虑将滚动位置存储在 URL 中,例如作为 URL 的哈希或查询参数。这样做有一个好处,用户可以直接通过共享 URL 来访问他们的阅读位置。

  • 保存位置:在用户滚动页面时,将滚动位置作为哈希或查询参数添加到 URL。
  • 恢复位置:当页面加载时,检查 URL 中是否有滚动位置,并滚动到该位置。

示例代码(使用 URL Hash):

// 保存滚动位置到 URL hash
window.addEventListener('scroll', () => {
    window.location.hash = `#scrollPosition=${window.scrollY}`;
});

// 页面加载时恢复滚动位置
window.addEventListener('load', () => {
    const hash = window.location.hash;
    if (hash && hash.startsWith('#scrollPosition=')) {
        const savedPosition = hash.split('=')[1];
        window.scrollTo(0, parseInt(savedPosition, 10));
    }
});

4. 使用 IntersectionObserver

如果你有长文章或者页面内容,想要精准地记录用户上次阅读的位置,可以考虑结合 IntersectionObserver 来监控用户是否看到了某个特定元素,并记录该元素的位置。

  • 保存位置:当用户阅读到页面的某个部分时,记录该部分的 ID 或元素位置。
  • 恢复位置:页面加载时,判断是否有记录过的位置,并自动滚动到对应的位置。

示例代码:

const observer = new IntersectionObserver((entries) => {
    entries.forEach(entry => {
        if (entry.isIntersecting) {
            localStorage.setItem('lastReadElement', entry.target.id);
        }
    });
});

// 监控所有段落元素
document.querySelectorAll('p').forEach(p => observer.observe(p));

// 页面加载时恢复阅读位置
window.addEventListener('load', () => {
    const lastReadElementId = localStorage.getItem('lastReadElement');
    if (lastReadElementId) {
        const lastElement = document.getElementById(lastReadElementId);
        if (lastElement) {
            lastElement.scrollIntoView();
        }
    }
});

5. 结合服务器端存储(如果适用)

如果你的应用有登录功能,并且希望让用户跨设备保持上次阅读位置,那么可以考虑将阅读位置存储在服务器端。每次用户访问页面时,向服务器发送请求,获取该用户上次的阅读位置并恢复。

总结

  • 如果是简单的页面,不涉及用户登录,LocalStorage 是最简单的选择。
  • 如果需要跨页面或浏览器会话保存,使用 CookieLocalStorage 都是不错的选择。
  • 如果想要通过 URL 直接共享位置,使用 URL HashQuery 参数
  • 对于更复杂的需求,结合 IntersectionObserver 可以实现更精准的内容跟踪。

根据你的需求,选择合适的方案。如果是小型项目,LocalStorage 通常已经足够。