何时使用无限滚动

如果你正在建立一个移动应用或社交媒体应用,或者只是想让用户连续滚动浏览大量内容(即博客),你应该使用无限滚动。

无限滚动如何工作

当用户到达视口的末端时,你会加载更多的结果。在普通的JavaScript中,它是这样工作的。

window.onscroll = function(ev) {
    if ((window.innerHeight + window.scrollY) >= document.body.offsetHeight) {
        // you're at the bottom of the page, load more content here.
    }
};
 
// from stackoverflow (stackoverflow.com/questions/9439725/javascript-how-to-detect-if-browser-window-is-scrolled-to-bottom)

我画了一个图来帮助解释数据是如何被遍历的,以及光标是如何工作的。

所以,想象一下,你查询后端API,数据库中总共有90万个条目。你不会想要获取所有的条目,因为这会降低应用程序的性能。

提示💡

为了简化,让我们用数字9来代替90万。

为了显示这些数据,你必须把它分成多个部分。它不一定要以相等的时间间隔显示,但通常是这样。这里是数据库中所有条目的列表。

{
  "data": [
    { id: 1 },
    { id: 2 },
    { id: 3 },
    { id: 4 },
    { id: 5 },
    { id: 6 },
    { id: 7 },
    { id: 8 },
    { id: 9 }
  ]
}

现在,因为一次性获取它们并不可行,你可以从后台的数据库中分块获取数据。

对于第一个结果,你只想获取前三个条目。

为了获取第一页,在数据库中查询 “前3条,后0条”。对于获取第二页,查询 “获取前3条,后3条”,以此类推。

你也可以使用术语limit/offset ,而不是first/skip 。

对于分页数据的获取,另一种经常使用的方法叫做游标。当使用游标时,“after “值被用来获取特定点之后的节点。

这里有一篇全面的文章,解释了为什么你可能想使用游标而不是limit/offset 方法。

当后端从数据库中获取选择性数据时,它会发送一个响应,通常看起来像这样。

{
  "data": [
    { id: 4 },
    { id: 5 },
    { id: 6 }
  ],
  "totalCount": 9,
  "fetchedCount": 3,
  "pageInfo": {
    "prevCursor": "prev_4", // <- this is usually converted to base64
    "nextCursor": "after_6", // <- this is usually converted to base64
    "hasNextPage": true // <- are there more pages remaining to fetch?
  }
}

然后,前端在这些游标上进行迭代,以获取分页数据的页面。

这个方法对于分页、“加载更多 “和无限滚动都是类似的,所以你可以通过使用上述方法获取数据来实现所有这些。

对于正常的分页,你必须同时使用next 和previous 光标。对于 “加载更多 “和无限滚动,你只需要next 游标,因为你必须通过它们来迭代,以不断获取更多的数据。