DOM 数量固定的无限滚动列表

1,602 阅读2分钟

什么?

昨天看了一个简洁、有趣的无限下拉方案这篇文章,感觉有点儿意思,想着有什么办法能实现不固定列表高度的版本吗?

关于 intersectionObserver 这个 API,可以看这篇文章:谈谈IntersectionObserver懒加载,讲得很详细。

思路

关键在于用 padding 来替换不可见区域的列表项,如何获取这个 padding 呢?

无限滚动列表其实就是一个分页组件,如果不是去获取每一项的高度,而是获取每一页的高度呢?

然后用固定数量的页数来渲染列表,超出屏幕的页数就获取每页的高度用 padding 来代替,看起来好像可行。

不是很擅长画图,将就看一下:

Untitled Diagram _1_.jpg

  1. intersectionObserver 监听 firstItem 和 lastItem。
  2. 当 firstItem 出现在屏幕上,获取最下面 page 的高度,把最下面的 page 换成 paddingBottom。往上层新加一个 page,同时 paddingTop 减去新加 page 的高度,并重置 firstItem 和 lastItem 的监听。
  3. 当 lastItem 出现在屏幕上,和 firstItem 相反,区别在于需要判断请求新数据还是加载之前的数据。

其实理论上来说,只需要两页就能实现,并不需要三页。只要保证 firstItem 和 lastItem 不会同时出现在屏幕上就可以。

动手

demo: github.com/linghucq1/v…

Untitled.gif

就是用一个长度为 3 的数组 scrollList 来模拟三个页面。看别人说 intersectionObserver 会有不触发的问题,试了一下还没有遇到。

Untitled2.gif

另外顺便还看了篇文章 搞清clientHeight、offsetHeight、scrollHeight、offsetTop、scrollTop

这里 Infinite Scroll’ing the right way 有用原生 JS 实现的版本,使用了魔术数字,也就是固定的列表高度,替换成这种分页也是一样的。

完。