JavaScript——虚拟滚动原理及Demo

78 阅读1分钟

介绍

虚拟滚动,只有可视区的Dom会渲染,范围之外的会被隐藏或销毁。 (适用于海量数据的列表/表格)

优点

  • 节省网络资源、内存
  • 提高首屏加载时间
  • 提升用户体验感
  • 减少性能消耗

原理图

  image.png

Demo

<!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>
      #main {
        width: 500px;
        height: 400px;
        overflow: auto;
        margin: 0 auto;
        border: 1px solid #e9e2e2;
        will-change: scroll-position; /* 提升性能,滚动的更流畅 */
      }
      #list div {
        height: 100px;
        line-height: 50px;
        box-sizing: border-box; /*固定div高度*/
        border-bottom: 1px solid #e9e2e2;
      }
    </style>
  </head>
  <body>
    <div id="main">
      <div id="list"></div>
    </div>
  </body>
  <script>
    const listData = [];
    // 准备1000条数据
    for (let i = 0; i < 1000; i++) {
      listData.push(i);
    }
    // init:比可视区多渲染2个
    render([0, 1, 2, 3, 4, 5, 6]);

    main.addEventListener("scroll", (e) => {
      // 虚拟滚动核心代码
      let scrollTop = main.scrollTop;
      let number = Math.floor(scrollTop / 100);
      const data = listData.slice(number, number + 6);
      list.style.transform = `translateY(${100 * number}px)`;/*空白填充撑起滚动*/
      render(data);
    });

    function render(data) {
      let str = "";
      data.forEach((el) => {
        str += `
        <div>
            <span>${el}</span>
        </div>
        `;
      });
      list.innerHTML = str;
    }
  </script>
</html>

滚动时,可以看到item一直是6个

image.png