什么?
昨天看了一个简洁、有趣的无限下拉方案这篇文章,感觉有点儿意思,想着有什么办法能实现不固定列表高度的版本吗?
关于 intersectionObserver
这个 API,可以看这篇文章:谈谈IntersectionObserver懒加载,讲得很详细。
思路
关键在于用 padding
来替换不可见区域的列表项,如何获取这个 padding
呢?
无限滚动列表其实就是一个分页组件,如果不是去获取每一项的高度,而是获取每一页的高度呢?
然后用固定数量的页数来渲染列表,超出屏幕的页数就获取每页的高度用 padding
来代替,看起来好像可行。
不是很擅长画图,将就看一下:

- intersectionObserver 监听 firstItem 和 lastItem。
- 当 firstItem 出现在屏幕上,获取最下面 page 的高度,把最下面的 page 换成 paddingBottom。往上层新加一个 page,同时 paddingTop 减去新加 page 的高度,并重置 firstItem 和 lastItem 的监听。
- 当 lastItem 出现在屏幕上,和 firstItem 相反,区别在于需要判断请求新数据还是加载之前的数据。
其实理论上来说,只需要两页就能实现,并不需要三页。只要保证 firstItem 和 lastItem 不会同时出现在屏幕上就可以。
动手
demo: github.com/linghucq1/v…

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

另外顺便还看了篇文章 搞清clientHeight、offsetHeight、scrollHeight、offsetTop、scrollTop。
这里 Infinite Scroll’ing the right way 有用原生 JS 实现的版本,使用了魔术数字,也就是固定的列表高度,替换成这种分页也是一样的。
- 顺便推荐一个 GIF 录制工具: www.cockos.com/licecap/
- 和一个在线画图: www.draw.io/
完。