告别卡顿!现代浏览器下的高性能虚拟滚动表格实践

一说到虚拟滚动,很多人都觉得很神秘,其实真的去做了,也就明白了。我在前端表格插件智表ZCELL的研发过程中,就采用了虚拟滚动技术,很好的解决了大数据量加载的问题,算是一次真实的实践吧,下面我来逐步说明一下:

一、实现滚动条基本功能

这个就是一个基本的滚动条功能,实现滚动时,页面内容能够进行滚动,大家从网上自行寻找就能找到不少代码,我这里不详细展开。我的代码如下,这里主要需要确定一个是列表总高度,一个是视窗高度,这两个概念。列表总高度就是你要显示数据行的实际总高,视窗高度是你在页面上滚动时显示数据的可视化窗口高度。

function Scrollbar(book) {
    this.options = {
        listheight: 0, //list总高度

        viewheight: 0, //可视高度/视窗高度
        wheelSpeed: 6 //滚轮滚动速度
    };


    //其他代码
.............
}

二、 初始化滚动条

滚动条基本功能具备后,在实际页面使用时,首先要进行初始化

首先是列表总高度计算和视窗高度计算,列表总高度计算原理是每行行高*总行数,

视窗高度计算时根据你页面设置视窗的大小计算。

 // 表格行数据总高度
    var listHeight = sheet.GetlistHeight() + 60; // 加60是为了在末尾留白
    var viewHeight = book.viewCanvas.height / book.PixRatio - sheet.colHeadHeight; // 视窗高度
  

然后初始化滚动条,用计算后的列表总高度和视窗高度初始化即可。

//创建纵向滚动条滑块
    scrollbar_y.setOptions({ listheight: listHeight, viewheight: viewHeight });

三、 滚动条滚动定位视窗上下坐标

滚动条上下滚动时,动态计算滚动条顶部坐标,注意要每次滚动时都要计算,这里要注意计算的性能会影响滚动效果,注意代码效率,然后根据顶部坐标计算视窗显示数据的顶部坐标和底部坐标,根据两个坐标取中间的数据行,在页面上渲染这一部分数据即可。具体代码如下:

这里先取了滚动顶部坐标,根据顶部坐标计算了视窗上边界坐标和下边界坐标。

        //取行显示范围
        let scrollTop = scrollbar_y.GetScrollTop();
        book.viewStartY = scrollTop; //视窗上边界坐标
        book.viewEndY = scrollTop + viewHeight; //视窗下边界坐标 
        let viewEndY = Math.min(book.viewEndY, sheet.GetlistHeight());

四、 计算显示区域的开始行号和结束行号

然后计算视窗区域内对应的数据行的范围。我这里用getRowIndex 方法实现了根据坐标查找行号的功能,增加了按优先范围快速查找功能,这样能尽可能压缩查找时间消耗。

        let startrow, endrow;
        if (scrollTop - sheet.lastscrollTop > 0) {
            //正向滚动,向下
            let left_s = sheet.lastviewstartrow;
            let right_s = left_s + 200;

            startrow = sheet.getRowIndex(book.viewStartY, { left: left_s, right: right_s });
            endrow = sheet.getRowIndex(viewEndY, { left: startrow, right: startrow + 200 });
        } else {
            //负向滚动,向上
            let right_e = sheet.lastviewstartrow + 200;
            let left_e = right_e;

            endrow = sheet.getRowIndex(viewEndY, { left: left_e, right: right_e });
            startrow = sheet.getRowIndex(book.viewStartY, { left: endrow - 200, right: endrow });
        }

五、 对视窗区域内数据进行渲染

确定好当前要显示的数据范围后,对显示区域内数据进行初始化,并进行渲染即可。

         //再调用渲染显示功能,对这部分数据进行显示即可
        sheet.drawData(startrow, endrow, startcol, endcol);
 

小结

以上就是我的虚拟滚动实现的核心逻辑代码,希望能对大家有所启发,具体效果,大家感兴趣的可以到看智表插件演示程序,通过性能测试功能,体验虚拟滚动的效果,一般的应用应该都可以满足。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值