工作项目实现瀑布流向上滚动到顶加载上一页,向下滚动到底加载下一页。根据最小高度优先排列。
设计思想
v1: 一开始需求只有向下滚动到底加载下一页,默认初始加载第一页。从左到右从上到下排列。判断滚动条到达底部发出请求加载下一页。列数不是固定的,根据window的宽度跟单卡宽度的对比确定当前展示的列数,根据列数循环加载单卡,设置单卡的top和left样式。left可以直接根据index和列数来确定。top需要计算当前列之前数据的高度总和。
v2: 单卡中图片的高度差距较大导致在每列数据个数相同的情况下,高度差有可能很大。界面不美观。需求更新为按当前高度最小列排放数据。多添加了一个记录高度的数组变量,渲染也变成了优先渲染列数的div,每列div渲染该列的数据。需要先根据列数将当前已存在的数据结构变更成二元数组,方便后续渲染。每列的div只用根据列数设置left,每列中的数据只用根据当前列该数据之前的数据高度和来设置top。
v3: 列表模式和网格模式切换时,牵扯到数据更新的问题。需求设定,列表模式跳转到网格模式时,网格模式应该对应显示当前页,即列表模式为第三页则网格模式显示第三页。需求增加向上滚动到顶加载上一页的功能。
选择的方案
瀑布流布局:position=absolute,每个图设置top和left
监控滚动条的方案:onScroll方法,用Ref绑定滚动条组件范围。用钩子生成onScroll监控滚动条变化时进行函数内操作。也就是说,每次检测到滚动条变化都会去判断是否到达顶部或者到达底部,进而进行请求和数据更新。如果是上一页的数据,需要将新数据添加到原有数据之前并重新进行排列和渲染,如果是下一页数据,需要将新数据添加到原有数据之后,只需要排列渲染新数据。
遇到的问题
- 如果只在页面初始加载时生成一次onScroll,后续绑定事件不会更新,只会无限加载第二页,useEffect闭包问题。若每次检测到滚动条变化就生成一次onScroll就需要防抖方案。
- scrollTop + clientHeight 与 scrollHeight 到达底部时会出现不知名的0.几的误差,问题暂时不知道是为什么。会导致经常出现滚动条到底部但未能触发到底部操作的问题。所以通过判断时scrollHeight - 1来处理,但是这样就有一个新问题。原本只有到scrollTop + clientHeight >= scrollHeight这个节点才会触发一次onScroll到底操作,现在因为这1高度的差值导致在这1高度中会出现重复请求的问题,会出现一次加载多页但加载不完全问题,需要防抖或者控制请求结束前不会再次触发请求。
- 在页面加载最后一页时,有可能会因为数据不足而导致渲染高度不够未出现滚动条的情况,无法进行滚动条触发请求。所以在判断当前页为最后一页时,判断列最大高度是否超过scrollHeight,如果未超过,则给他底部添加填充div用来撑起页面使滚动条显示。
- 在页面初始渲染成功时,不管是在哪一页,滚动条都默认是顶部。在不触发向下滚动操作时,无法向上滚动,无法进行加载上一页的请求。所以在页码非第一页时,给顶部填充10px的div并将滚动条设定在10px的高度。使得视觉上和原来没有区别,并且有一定向上滚动区间去触发加载上一页操作。
- 由于未注意,用index值来作为列的key值导致重新渲染页面时,会出现上一次数据的残留冗余。
其他方法
- 直接在滚动条所在div中使用onScrollCapture来监控滚动条变化,不会有闭包问题,也没有出现高度差问题。
- 用现有的上拉加载下拉刷新组件(尝试、学习中)
- macy插件实现瀑布流布局
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。