基本原理
- 有一万条数据,我们按10条一页来进行分组,会有1000页
- 页面滚动到第10页的位置的时候,10页之后和10页之前是不用被显示的,可以直接隐藏掉
- 如果是数据删除,页面会不流畅,会卡顿一下,且滚动位置也会变
- 为了保证页面流畅性,我们可以前后各安置一个占位 view(div),前为 prev 后为 next
- 滚动的时候,动态的改变可视区域的内容且动态的改变前置占位和后置占位的高度
具体实现
简述
- js 部分,初始化计算出可视列表,前置占位高度,后置占位高度
- html 部分,在 scroll 时,调用js方法,更新可是列表,前置占位高度,后置占位高度
计算出可视列表,前置占位高度,后置占位高度
通过 scrollTop
我们可以精确知道往上滚动了多少项,此时可以精确计算出应该显示的项
- 我们首先给 list 所有项增加 pageNumber,以
10
项为一页 - 当滚动的时候通过如下计算,可能知道滚动了多少页,得到 scrolledPageNumber
// 滚动到不可见区域的 item 数量
const scrolledItemNumber = Math.floor(top / 50)
// 滚动到不可见区域的 page 数量
const scrolledPageNumber = Math.floor(scrolledItemNumber / 10)
- 为了保证快速滚动的时候,页面往前翻和往后翻都有数据【不出现空白】
我们将可视页码改为 前一页 + 当前页 + 后一页,注意兼容初始页【1,2,3】 的情况
- 根据 [5,6,7] 计算出可视列表,前后高度
// 获取当前可视页面号码数组
let visibleNumbers = virtualList.visiblePageNumbers
// 计算可视列表的起始位置(页码-1)乘以每页的项数
let start = (visibleNumbers[0] - 1) * pageSize
// 计算可视列表的结束位置(最后一页的页码)乘以每页的项数
let end = visibleNumbers[visibleNumbers.length - 1] * pageSize
// 如果起始位置小于0,则修正为0
if (start < 0) start = 0
// 如果结束位置大于列表总长度,则修正为列表的最后一个位置
if (end > virtualList.list.length - 1) end = virtualList.list.length
// 根据起始和结束位置,从总列表中提取出可视部分的列表
virtualList.visibleList = virtualList.list.slice(start, end)// 计算列表前的占位高度(起始位置乘以每项的高度)
virtualList.beforePlaceHeight = start * itemHeight
// 计算列表后的占位高度(总长度减去结束位置后的项数乘以每项的高度)
virtualList.afterPlaceHeight = (virtualList.list.length - end) * itemHeight