Skip to content
 

前端页面中,如何让用户回到上次阅读的位置

更新: 9/19/2025字数: 0 字 时长: 0 分钟

当用户中途离开页面,再次返回时,如何让他们回到上次阅读的位置,无论是在新闻网站、博客平台,还是长文档应用中,这个功能都很常用。

1. 使用 sessionStoragelocalStorage 实现回到上次阅读位置

1.1 sessionStoragelocalStorage 简介

在浏览器端,sessionStoragelocalStorage 都是用于存储数据的 Web 存储方式。它们的区别在于:

  • sessionStorage:在一个会话期间有效,当用户关闭浏览器时,数据会被清除。
  • localStorage:数据会永久保存在浏览器中,除非用户手动清除。

这两个 API 都可以用于保存用户的滚动位置,确保用户在刷新页面或重新访问时能够恢复到之前的位置。

1.2 实现步骤

保存滚动位置: 在用户滚动页面时,通过监听 scroll 事件,将当前的滚动位置保存到 sessionStoragelocalStorage 中。

恢复滚动位置: 在页面加载时,检查存储中是否有保存的滚动位置,如果有,使用 window.scrollTo 方法将页面滚动到该位置。

示例代码:

html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>回到上次阅读位置</title>
    <style>
      .content {
        height: 3000px;
        padding: 10px;
      }
    </style>
  </head>
  <body>
    <div class="content">
      <h1>这是一个测试页面</h1>
      <p>滚动内容...</p>
    </div>

    <script>
      // 保存滚动位置
      window.addEventListener("scroll", function () {
        sessionStorage.setItem("scrollPosition", window.scrollY);
      });

      // 页面加载时恢复滚动位置
      window.addEventListener("load", function () {
        const scrollPosition = sessionStorage.getItem("scrollPosition");
        if (scrollPosition) {
          window.scrollTo(0, scrollPosition);
        }
      });
    </script>
  </body>
</html>

1.3 优缺点

  • 优点:实现简单,适用于单页面应用和简单的内容滚动。
  • 缺点:仅适用于同一会话,如果使用 localStorage,它可能会保存太久的数据,可能影响用户隐私。

2. 使用 Intersection Observer API 实现回到上次阅读位置

Intersection Observer API 是现代浏览器提供的一种高效监测元素与视口交集的 API。它允许你异步观察目标元素与视口之间的交集状态,可以非常精确地判断用户当前阅读的页面位置,并在页面加载时自动回到上次阅读的部分。

2.1 Intersection Observer API 简介

Intersection Observer 允许你监听目标元素是否出现在视口中(或祖先元素中)。这个 API 的优势在于,它能高效地处理滚动事件,避免了传统 scroll 事件带来的性能开销。

2.2 实现步骤

  1. 监听目标元素(例如文章段落、特定的内容块)是否进入视口。
  2. 当目标元素进入视口时,保存当前的滚动位置。
  3. 页面加载时,根据保存的滚动位置恢复页面。

示例代码:

html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>回到上次阅读位置</title>
    <style>
      .content {
        height: 3000px;
      }
      .target {
        margin-top: 1000px;
        height: 100px;
        background-color: lightcoral;
      }
    </style>
  </head>
  <body>
    <div class="content">
      <h1>我的文章</h1>
      <div class="article">
        <p>文章段落 1</p>
        <p>文章段落 2</p>
        <p>文章段落 3</p>
        <div id="target" class="target"></div>
        <!-- 用户可能停止阅读的位置 -->
        <p>文章段落 4</p>
        <p>文章段落 5</p>
      </div>
    </div>

    <script>
      const targetElement = document.getElementById("target");
      const lastScrollYKey = "lastScrollPosition";

      // 创建 IntersectionObserver 实例
      const observer = new IntersectionObserver(
        (entries) => {
          entries.forEach((entry) => {
            if (entry.isIntersecting) {
              // 保存用户最后看到的滚动位置
              sessionStorage.setItem(lastScrollYKey, window.scrollY);
            }
          });
        },
        { threshold: 0.5 }
      ); // 设置阈值为 50%

      // 观察目标元素
      observer.observe(targetElement);

      // 恢复滚动位置
      window.addEventListener("load", () => {
        const savedPosition = sessionStorage.getItem(lastScrollYKey);
        if (savedPosition) {
          window.scrollTo(0, savedPosition);
        }
      });
    </script>
  </body>
</html>

2.3 优缺点

  • 优点IntersectionObserver 不会像传统的 scroll 事件那样频繁触发,因此性能更好。同时,它可以精确判断某个元素是否在视口内,适用于需要精确控制滚动的场景。
  • 缺点:需要较新的浏览器支持,尽管大多数现代浏览器已经支持,但对于老版本浏览器需要引入 polyfill。

3. 使用 URL Hash 实现回到上次阅读位置

通过 URL 的 hash 部分保存滚动位置是一种简单且有效的方式。这种方法的优点是,它可以利用浏览器的历史记录系统,使得每次用户滚动时,都可以通过 URL 记录下当前阅读的位置。

3.1 实现步骤

  1. 每次用户滚动时,将滚动位置保存到 URL 的 hash 部分。
  2. 页面加载时,从 URL 的 hash 中读取滚动位置并恢复。

示例代码:

html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>回到上次阅读位置</title>
    <style>
      .content {
        height: 3000px;
      }
      .target {
        margin-top: 1000px;
        height: 100px;
        background-color: lightcoral;
      }
    </style>
  </head>
  <body>
    <div class="content">
      <h1>我的文章</h1>
      <div class="article">
        <p>文章段落 1</p>
        <p>文章段落 2</p>
        <p>文章段落 3</p>
        <div id="target" class="target"></div>
        <!-- 用户可能停止阅读的位置 -->
        <p>文章段落 4</p>
        <p>文章段落 5</p>
      </div>
    </div>

    <script>
      // 保存滚动位置到 URL Hash
      window.addEventListener("scroll", function () {
        const scrollPosition = window.scrollY;
        window.location.hash = scrollPosition; // 将滚动位置作为哈希值保存
      });

      // 页面加载时恢复滚动位置
      window.addEventListener("load", function () {
        if (window.location.hash) {
          const scrollPosition = parseInt(window.location.hash.slice(1)); // 获取哈希值并去掉 #
          if (scrollPosition) {
            window.scrollTo(0, scrollPosition); // 恢复滚动位置
          }
        }
      });
    </script>
  </body>
</html>

3.2 优缺点

  • 优点:使用浏览器的 URL Hash,能够利用浏览器的历史记录和导航机制,适用于有多部分内容需要跳转的场景。
  • 缺点:每次更新滚动位置都会修改 URL,可能会影响用户体验,不适合频繁更新的场景。

我见青山多妩媚,料青山见我应如是。