最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 虚拟列表初探

    正文概述 掘金(懒狗小前端)   2021-06-28   628

    前言

    虚拟列表,顾名思义,不是真实的列表,它一般只存在于人类的美好遐想之中...

    跑题了,重来。

    这话是引用element-plus中的,我觉得说的挺有道理,就小小地借鉴一下。虚拟列表的出现是为了解决列表中数据内容过长,过多,导致的加载缓慢和快速滚动白屏。

    开始

    首先,先来看一个例子 我们再container中,动态添加20000个列表项,高度固定24,会发现页面加载时,出现了明显的延迟卡顿。

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <title>Title</title>
      <style>
        #container {
            width: 240px;
            height: 300px;
            margin-top: 24px;
            overflow-y: auto;
        }
      </style>
    </head>
    <body>
    <div>list-container: </div>
    <div id="container"></div>
    <script>
      const NUMBER = 20000, HEIGHT = 24;
      const container = document.getElementById('container');
      let str = ``;
      for (let i = 0; i < NUMBER; i++) {
        let s = ``;
        s += `
          <div
            style="height: 24px;display: flex;align-items: center;box-sizing: border-box
            justify-content: space-between;font-size: 14px;border-bottom: 1px solid #ddd;"
          >
            <div>list</div>
            <div>${i}</div>
          </div>
        `
        str += s;
      }
      container.innerHTML = str;
    </script>
    </body>
    </html>
    

    简单的一个列表需要0.8秒的时间,而且拖动滑块快速滑动时,有时还会出现短暂的空白情况。

    虚拟列表初探

    解决

    为了更好的客户体验,我们可以使用虚拟列表来解决这个问题。

    原理很简单,监听滚动事件时,我们通过视窗的高度,和滚动条的滚动距离,来计算出当前应该显示给使用者的列表,并在前后补充几个作为缓冲。

    然后根据滚动距离,通过 定位 或者 translate偏移 将列表移动到当前显示的位置。在客户的感知中,与正常列表无异,而实际上,我们一直只渲染了这十几二十个列表项。

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <title>Title</title>
      <style>
          #container {
              width: 240px;
              height: 300px;
              margin-top: 24px;
              overflow-y: auto;
          }
          #list-container {
              position: relative;
          }
          #scroll-div {
              width: 100%;
              position: absolute;
              top: 0;
              left: 0;
          }
      </style>
    </head>
    <body>
    <div>list-container: </div>
    <div id="container">
      <div id="list-container">
        <div id="scroll-div"></div>
      </div>
    </div>
    <script>
      const NUMBER = 20000, HEIGHT = 24;
      const container = document.getElementById('container');
      const scrollDiv = document.getElementById('scroll-div');
      const listContainer = document.getElementById('list-container');
      listContainer.style.height = NUMBER * HEIGHT + 'px';
      const height = container.offsetHeight;
      // 取超过高度的数量
      const num = Math.ceil(height / 24);
    
      // 滚动时候的回调函数
      const scrollCallback = function(e) {
        const h = e ? e.target.scrollTop : 0;
        console.log('h', h);
        // 找到该显示列表中的第几个,然后加上num,再往前取5个,往后取5个,得到需要渲染的列表
        const n = Math.ceil(h / HEIGHT);
        const start = n > 5 ? n - 5 : 0;
        const end = n + (num - 1) > NUMBER - 5 ? NUMBER : n + (num - 1) + 5;
        let str = ``;
        for (let i = start; i < end; i++) {
          let s = ``;
          s += `
            <div
              style="height: 24px;display: flex;align-items: center;box-sizing: border-box;
              justify-content: space-between;font-size: 14px;border-bottom: 1px solid #ddd;"
            >
              <div>list</div>
              <div>${i}</div>
            </div>
          `;
          str += s;
        }
        const top = start * HEIGHT;
        scrollDiv.style.top = top + 'px';
        scrollDiv.innerHTML = str;
      }
      // 初始化
      scrollCallback();
      // 监听滚动事件
      container.onscroll = scrollCallback;
    </script>
    </body>
    </html>
    

    虚拟列表初探

    结语

    仅仅是一次简单的虚拟列表的实现,因为高度都是固定的,十分有局限性。由于这次是初探,宽以待己,争取下次中探时候,能找到自适应高度的良好解决方法。

    由于最近沉迷炉石战棋,加上对flutter继续“坚持不懈”的探索与学习,我终于上到了5500分。导致这个文章写得太少太浅,深感愧疚,自我鞭策一下,以后尽量还是保证一礼拜至少写一篇吧。


    起源地下载网 » 虚拟列表初探

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元