Intersection Observer API 实现无限滚动

使用Intersection Observer API实现无限滚动的功能


利用Intersection Observer API已经实现滚动时图片的动态加载效果, 其实它还可以实现一个非常常见的功能 - 无限滚动


完整代码

html 复制代码
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>无限滚动 Intersection Observer</title>
    <style>
      #container {
        max-width: 400px;
        margin: 0 auto;
      }
      .item {
        padding: 16px;
        border-bottom: 1px solid #ccc;
      }
      #loading {
        height: 30px;
      }
    </style>
  </head>
  <body>
    <div id="container"></div>
    <div id="loading">loading...</div>

    <script>
      const container = document.getElementById("container");
      const loading = document.getElementById("loading");
      let page = 1;
      const maxPage = 5;

      function loadMore() {
        if (page > maxPage) {
          loading.textContent = "没有更多内容了";
          observer.unobserve(loading);
          return;
        }
        for (let i = 0; i < 10; i++) {
          const div = document.createElement("div");
          div.className = "item";
          div.textContent = `第${(page - 1) * 10 + i + 1}条内容`;
          container.appendChild(div);
        }
        page++;
      }

      // initial load
      loadMore();

      const observer = new IntersectionObserver((entries) => {
        if (entries[0].isIntersecting) {
          loadMore();
        }
      });

      observer.observe(loading);
    </script>
  </body>
</html>

实现效果:

无限滚动的技术实现

Intersection Observer API 简介

Intersection Observer API
性能更好:不依赖主线程,减少性能开销

实现更简单:无需复杂的滚动位置计算

配置灵活:可设置阈值、根元素和边距

更可靠:自动处理元素位置变化

实现步骤详解

1. 创建观察器
javascript 复制代码
const observer = new IntersectionObserver((entries) => {
  if (entries[0].isIntersecting) {
    loadMore();
  }
}, {
  rootMargin: '50px'
});

创建了一个IntersectionObserver实例,它会在目标元素进入视口时触发回调函数。rootMargin选项允许我们在元素实际进入视口前提前触发加载,提供更流畅的用户体验.

2.设置观察目标
javascript 复制代码
const loading = document.getElementById("loading");
observer.observe(loading);

指定页面底部的loading元素作为观察目标。当这个元素进入视口时,就会触发加载新内容的操作.

3. 加载更多内容
javascript 复制代码
let page = 1;
const maxPage = 5;

function loadMore() {
  if (page > maxPage) {
    loading.textContent = "没有更多内容了";
    observer.unobserve(loading);
    return;
  }
  for (let i = 0; i < 10; i++) {
    const div = document.createElement("div");
    div.className = "item";
    div.textContent = `第${(page - 1) * 10 + i + 1}条内容`;
    container.appendChild(div);
  }
  page++;
}

在loadMore函数中,我们首先检查是否还有更多内容可加载。如果没有,则显示结束消息并停止观察。否则,创建新内容项并添加到页面中。(通过maxPage模拟没有更多数据加载)

总结

相比于传统的滚动事件监听方案,Intersection Observer API具有更好的性能和更简洁的实现方式,是现代Web开发中处理滚动相关功能的推荐方案。