需求背景

xxx模块,表格涉及了左右列固定以及树形数据展示。
在数据量大的情况下,表格是渲染全量DOM,会导致页面渲染、树的操作卡顿,体验很差

业务要求

根据视图可展示的数据条数进行动态计算渲染的数据,按需渲染dom

实现思路

虚拟表格是按需显示思路的一种实现,即虚拟表格是一种根据滚动容器元素的可视区域来渲染长表格数据中某一个部分数据的技术。
简而言之,虚拟表格指的就是「可视区域渲染」的表格。有三个概念需要了解一下:

  • 滚动容器元素:一般情况下,滚动容器元素是 window 对象。然而,我们可以通过布局的方式,在某个页面中任意指定一个或者多个滚动容器元素。只要某个元素能在内部产生横向或者纵向的滚动,那这个元素就是滚动容器元素以ant的表格为例,滚动元素即为.ant-table-body
  • 可滚动区域:滚动容器元素的内部内容区域。假设有 100 条数据,每个表格项的高度是 50,那么可滚动的区域的高度就是 100 * 50。可滚动区域当前的具体高度值一般可以通过(滚动容器)元素的 scrollHeight 属性获取。可以通过滚动来改变表格在可视区域的显示部分。
  • 可视区域:滚动容器元素的视觉可见区域。如果容器元素是 window 对象,可视区域就是浏览器的视口大小(即视觉视口);如果容器元素是某个 div 元素,其高度是 300,右侧有纵向滚动条可以滚动,那么视觉可见的区域就是可视区域。

实现虚拟表格就是在处理用户滚动时,要改变表格在可视区域的渲染部分,其具体步骤如下:

  • 计算当前可见区域起始数据的 startIndex
  • 计算当前可见区域结束数据的 endIndex
  • 计算当前可见区域的数据,替换表格的data-source,并渲染到页面中
  • 缓存值即为预先在视图外加载好的数据,默认偶数,假设缓存值为6(分为3种情况)

    • 1.当表格滚动到顶部。顶部缓存值为0,底部为6
    • 2.当表格在滚动过程中,见下图。顶部缓存值为3,底部为3(均分)
    • 3.当表格滚动到底部。顶部缓存值为6,底部为0

计算可渲染个数:visibleCount

计算视图区域能放下多少个tr
公式:Math.ceil(可视区域高度 / 单条数据高度) + 缓冲值
缓冲值的作用是为了在滚动数据的过程中使得数据显示不那么突兀。

计算下标:startIndex、endIndex

可渲染个数visibleCount上一步已经计算得出

  • 初始化或者滚动高度为0的情况:

startIndex值为0,endIndex的值即为startIndex+visibleCount

  • 滚动的情况:计算滚动条数:scrollCount根据单次滚动的scrollTop(newScrollTop-oldScrollTop)除以单个tr的高度。结果向上取整即为scrollCount的值这里需要缓存上次滚动的位置高度,在基于新的滚动高度计算单次滚动的scrollTop;startIndex = startIndex + scrollCount

endIndex= startIndex + visibleCount

  • 滚动到底部
    endIndex= 源数据.length
    startIndex = endIndex - scrollCount

    偏移table,撑开滚动条

    每次滚动的时候,将transform: translateY(px)添加到table上,偏移值即为滚动条的`scrollTop树形表格

    树形表格

    将树形数据扁平化处理,子集数据处理带上父级path路径以及level。
    父级path的作用是处理点击父集展开底下全部所属子集
    level的作用是处理树形的层级样式突进

关键技术

实现难点在于动态计算数据的起始下标问题,并正确渲染视图的位置
树形的难点在于处理数据的展开收起,动态渲染数据的逻辑
table06 .gif


雾岛听风
12.1k 声望8.6k 粉丝

丰富自己,胜过取悦别人。