后端返回几百万数据怎么渲染

91 阅读1分钟

虚拟列表渲染

    *{
      margin: 0;
      padding: 0;
    }
    
    body {
      display: flex;
      height: 100vh;
      justify-content: center;
      align-items: center;
    }
    
    .container {
      width: 600px;
      height: 500px;
      border: 2px solid #ccc;
      overflow-y: auto;
    }
    
    .list {
      background-color: #eee;
    }
    
    .item:hover {
      background-color: #409eff;
      color: #fff;
    }
  <div class="container">
    <div class="list"></div>
  </div>
  const data = [];
  for(let i = 0; i < 10000; i++) {
    data.push(`oh my name is ${i + 1}`);
  }
  
  const outerContainer = document.getElementsByClassName('container')[0];
  const innerContainer = document.getElementsByClassName('list')[0];
  
  const itemHeight = 60; // 每一项高度
  const height = 500; // 外层容器高度
  
  // const contentHeight = data.length * itemHeight; // 先算出总的高度
  // innerContainer.style.height = contentHeight + 'px';
  
  function scrollEvent() {
    // 算出滚动的距离,获取 startIndex
    let startIndex = Math.floor(outerContainer.scrollTop / itemHeight);
    let endIndex = startIndex + Math.ceil(height / itemHeight);
    
    // 获取需要渲染的数据
    let renderData = data.slice(startIndex, endIndex);
    
    // 渲染数据
    innerContainer.innerHTML = '';
    let html = '';
    renderData.forEach(item => {
      html += `<div class="item" style="height: ${itemHeight}px; text-align: center; line-height: ${itemHeight}px">${item}</div>`;
    })
    innerContainer.innerHTML = html;
    
    // 设置偏移量
    const innerTop = startIndex * itemHeight;
    const innerBottom = (data.length - endIndex) * itemHeight;
    innerContainer.setAttribute('style', `padding-top: ${innerTop}px; padding-bottom: ${innerBottom}px`);
  }
  
  // 首屏加载
  scrollEvent()
  
  outerContainer.addEventListener('scroll', scrollEvent)