虚拟滚动的方案

1. 为什么需要使用虚拟滚动技术?

在前端开发中,会碰到一些不能使用分页方式来加载列表数据的业务形态,我们称这种列表叫做长列表。比如ant-design下拉框的数据项,如果直接将所有的数据都生成dom,页面会非常卡顿。

因此,虚拟滚动的核心思想就是只加载可视区域内需要的列表项,当滚动发生时,动态通过计算获得可视区域内的列表项,并将非可视区域内存在的列表项删除。

2. 关键技术点?

 

 

dom结构上,需要一个视窗容器(visualContainer)、一个让视窗具备滚动条的占位子元素(placeholderDom),一个呈现可视区域数据的容器(dataContainer);

根据视窗高度和行高(itemHeight),可得出视窗能显示的条数(visualNum);

根据行高和总数据量,可得出占位子元素的高度(totalHeight);

根据滚动条的位置/行高,可得出当前应显示数组的开始下标(startIndex),通过startIndex+visualNum,得出数组的结束下标(endIndex);使用数组的slice(startIndex,endIndex)取出需要显示的数据(displayData);

displayData的数据显示在dataContainer中,dataContainer在默认情况下相对container的坐标始终是(0,0),当视窗滚动时,需要移动dataContainer的位置,移动的位置(startOffset) = (新的startIndex - 上一次的startIndex)*itemHeight;

为了防止页面整体回流,将dataContainer的position设为absolute,并使用css3的transform:tanslateY来开启gpu加速;

为了避免快速滚动时频繁更新dom导致页面出现空白、卡顿,需要使用window.requestAnimationFrame方法来处理滚动回调;

 

3. 具体实现

简单版

缺点:只要有滚动就重新计算需要取出的数据,导致dom频繁更新

 

复杂版

demo

使用了滚动条分页概念,当滚动条到达边界数据时,计算新一页的数据,同时为了让边界数据前后可浏览器,一般会在前后各增加一页缓冲数据。

 

posted @ 2020-09-28 11:22  我是格鲁特  阅读(543)  评论(0编辑  收藏  举报