React虚拟滚动列表

开发思路解析
  • 实现效果,永远只渲染在可视区域的DOM数据
  • 计算容器展示所有数据的时候的高度
  • 滚动计算动态显示的开始下标和结束下标
  • slice截取显示的数据, 数据整体transformY之前数据的高度
  • 瀑布流布局的情况,对不同的列计算高度,最大高度为容器高度
    滚动过程中计算可视区域到滚动容器顶部的距离有一定难度
模拟数据,固定高度50一行
  createMockData = () => {
    let data = [];
    for (var i = 1; i < 10001; i++) {
      data.push(`${i}: 第${i}个>>>>>>>>>>>>>>>>>>>>>>`)
    }
    this.setState({
      mockData: data
    })
    this.refs.scrollBody.style.height = 10000 * 50 + "px";
    const canSeeNums = Math.ceil(Number(this.refs.wrrapCpntainer.style.height.split("px")[0]) / 50) + 2;
    this.setState({
      tail: canSeeNums,
      canSeeNums: canSeeNums,    // 可展示的数量+2
      itemHeight: 50
    })
  }
滚动动态计算 head、tail,展示的节点开始结束
  handSrcoll = (e) => {
    if (e.target.scrollTop) {
      this.setState({
        head: Math.ceil((e.target.scrollTop - this.state.itemHeight + 10) / this.state.itemHeight),
        tail: Math.ceil(e.target.scrollTop / this.state.itemHeight) + 11
      })
    } else {
      this.setState({
        head: 0,
        tail: this.state.canSeeNums
      })
    }
  }

  deBounce = (fn, timeOut = 100) => {
    let setTime;
    return function (...args) {
      let flag = true;
      if (flag) {
        fn.apply(this, args);
      }
      setTime = setTimeout(() => {
        flag = false;
        clearTimeout(setTime)
      }, timeOut)
    }
  }
结构

如果不是固定高度的行,需要动态计算之前数据占据的高度,在设置transformY
给滚动加上防抖避免触发过多的判断

          
{/** 滚动容器 */}
{(renderData.slice(head, tail)).map((item) => (
{item}
))}

你可能感兴趣的:(React虚拟滚动列表)