使用JavaScript制作虚拟滚动小组件

42 min read

以下是使用 JavaScript 实现虚拟滚动小组件的示例:

<div id="virtual-scroll">
  <div class="viewport">
    <div class="content">
      <!-- 内容区域 -->
    </div>
  </div>
</div>
#virtual-scroll {
  position: relative;
  width: 300px;
  height: 200px;
  overflow: auto;
}

.viewport {
  position: relative;
  width: 100%;
  height: 100%;
  overflow: hidden;
}

.content {
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: auto;
}
const ITEM_HEIGHT = 50; // 单个元素高度
const VISIBLE_ITEMS = 4; // 可见元素个数

const $viewport = document.querySelector('.viewport');
const $content = document.querySelector('.content');

// 生成大量元素
const items = [];
for (let i = 0; i < 10000; i++) {
  const $item = document.createElement('div');
  $item.classList.add('item');
  $item.innerText = i;
  $content.appendChild($item);
  items.push($item);
}

function updateScrollTop() {
  const scrollTop = $content.scrollTop;
  const start = Math.floor(scrollTop / ITEM_HEIGHT);
  const end = start + VISIBLE_ITEMS + 1;

  // 遍历元素,设置显示或隐藏
  items.forEach(($item, index) => {
    if (index >= start && index <= end) {
      $item.style.display = 'block';
    } else {
      $item.style.display = 'none';
    }
  });

  // 设置 viewport 的高度,防止出现滚动条
  $viewport.style.height = `${ITEM_HEIGHT * items.length}px`;
}

// 监听滚动事件
$viewport.addEventListener('scroll', updateScrollTop);

// 页面打开时更新滚动位置
updateScrollTop();

以上代码是一个虚拟滚动小组件,其中包括一个滚动容器 #virtual-scroll,其中包含一个视口 .viewport 和一个内容区 .content。在使用时需要注意,视口和内容区的尺寸应该在 CSS 中动态设置,以确保内容区域可以正确地滚动。

在 JavaScript 中,我们通过 ITEM_HEIGHTVISIBLE_ITEMS 定义了单个元素的高度和可见元素的个数。在程序运行时,我们会读取滚动容器的 scrollTop 值,并根据其中可见区域的起止位置计算哪些元素应该显示,哪些元素应该隐藏。计算出来后,我们就可以遍历所有元素并设置相应的显示和隐藏样式了。

最后,为了防止出现滚动条,我们需要在更新滚动位置时动态设置视口的高度,以确保滚动容器的高度不变。