前端优化渲染:长列表渲染

js实现长列表渲染

众所周知,DOM多了之后,页面会变得很卡顿。有时候又不得不渲染很多数据,比如长列表,这时就需要前端做一些渲染优化了。

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      * {
        padding: 0;
        margin: 0;
      }
      div,
      ul,
      li {
        box-sizing: border-box;
      }

      ul,
      li {
        list-style: none;
      }

      .scroll {
        margin: 50px auto;
        width: 500px;
        height: 300px;
        overflow-y: auto;
        background-color: pink;
      }

      .item {
        width: 100%;
        height: 50px;
        border: 1px solid #b2ceeb;
        margin-bottom: 5px;
      }

      .item:last-child {
        margin-bottom: 0;
      }
    </style>
  </head>
  <body>
    <div class="scroll">
      <ul class="container"></ul>
    </div>
  </body>
</html>
<script>
  // 获取滚动元素和列表容器元素
  const scrollEle = document.querySelector(".scroll");
  const containEle = document.querySelector(".container");

  const scrollArea = scrollEle.clientHeight; // 可视区域的高度
  const itemH = 50; // 每一个项目的高度(定高)
  const size = Math.ceil(scrollArea / itemH); // 可视区域能展示的条数

  // 初始化数据列表
  const dataList = new Array(10000);

  function scrollFn() {
    const scrollTop = scrollEle.scrollTop; // 获取滚动距离
    const first = Math.floor(scrollTop / itemH); // 根据滚动距离和列表高度计算出当前视图中第一条数据的索引
    const end = first + size; // 计算视图中最后一条数据的索引
    const data = dataList.slice(first, end); // 根据索引截取视图所展示的数据
    // 拼装截取的数据
    let box = "";
    for (let i = 0; i < data.length; i++) {
      box += `<li class="item">${first + 1 + i}</li>`;
    }
    containEle.innerHTML = box; // 内容替换

    // 通过给列表容器设置padding值来保证滚动条的位置正确
    const paddingTop = first * itemH;
    const paddingBottom = (dataList.length - end) * itemH;
    containEle.setAttribute(
      "style",
      `padding-top: ${paddingTop}px; padding-bottom: ${paddingBottom}px`
    );
  }
  document.onload = scrollFn(); // 初始化渲染
  scrollEle.onscroll = scrollFn;
</script>

上面这种方式只是适用于数据是一次性给的情况。其实我个人觉得,数据多了最好和后端协商一下,让后端做分页处理。全靠前端的话,局限性比较大。哪怕做了虚拟列表处理,数据过大的情况下,还是展示不全。
目前我测试过的谷歌浏览器的页面的最大宽/高是33554400px,如果超过这个宽度/高度,会被默认切掉。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值