长文 / 小说 / 文档必备!前端实战:如何让用户精准回到上次阅读处

106 阅读2分钟

在阅读类、资讯类、博客类网站中,记忆用户上次阅读到的位置,并在下次访问时自动滚动回那个位置,可以大大提升用户体验感。体验可前往我的新项目:NBtab新标签页

解决方案一:Intersection Observer + 插入探针元素

Intersection Observer在确定页面位置的时候有奇效,但是如果存在大块、不宜分割或者杂乱的元素,那么监听元素的选择就会成为一个问题。

添加探针元素可以有效解决这个问题,探针元素只需要小小一个 div,可以设置为 visibility: hidden,不影响页面布局。他们就像一个个哨兵,负责观察你的视口到了什么位置。

1、页面插入探针元素

可以在重要段落、章节、标题前插入隐形的小 div。

<article>
  <div id="section-1" class="observer-marker"></div>
  <h2>第一章 标题</h2>
  <p>正文内容...</p>
 
  <div id="section-2" class="observer-marker"></div>
  <h2>第二章 标题</h2>
  <p>正文内容...</p>
 
  <!-- 更多内容 -->
</article>

2、设置 Intersection Observer,并在页面加载时,滚动到探针位置

// 创建 IntersectionObserver 实例
const observer = new IntersectionObserver((entries) => {
  entries.forEach(entry => {
    if (entry.isIntersecting) {
      // 如果探针元素进入可视区,记录它的id
      localStorage.setItem('lastVisibleSectionId', entry.target.id);
    }
  });
}, {
  threshold: 0.5 // 元素至少50%可见时触发
});
 
// 监听所有探针元素
document.querySelectorAll('.observer-marker').forEach(marker => {
  observer.observe(marker);
});
 
// 页面加载时,恢复到上次记录的探针
window.addEventListener('DOMContentLoaded', () => {
  const lastId = localStorage.getItem('lastVisibleSectionId');
  if (lastId) {
    const element = document.getElementById(lastId);
    if (element) {
      element.scrollIntoView({ behavior: 'smooth' }); // 平滑滚动到探针
    }
  }
});

解决方案二:基于 URL Hash 锚点跳转

给每一节内容设置唯一 id,用户阅读到某个位置时,自动更新 URL 的 hash(锚点 #id),页面加载时,浏览器根据 hash 自动滚动到对应位置。这种方式实现的跳转甚至可以实现分享,因为位置信息是保存在 URL 里面的。

// 监听页面滚动,动态更新 URL Hash
const observer = new IntersectionObserver((entries) => {
  entries.forEach(entry => {
    if (entry.isIntersecting) {
      // 动态替换地址栏 hash,不刷新页面
      history.replaceState(null, '', `#${entry.target.id}`);
    }
  });
}, {
  threshold: 0.5
});
 
// 监听所有需要作为锚点的元素
document.querySelectorAll('.observer-marker').forEach(marker => {
  observer.observe(marker);
});
 
// 页面刷新后,浏览器会自动滚动到hash对应的元素
结语

 实现回到上次阅读位置,并不只有一种方式,关键是根据你的项目特点选择:

  • 内容结构清晰 ➔ Intersection Observer是最佳。
  • 需要分享/跳转 ➔ 用 URL Hash 最自然。

有兴趣交流的朋友可以在NByab新标签页设置页面关于我们加我新项目的内测群交流,点击前往NBtab新标签页