Open gdutjason opened 1 year ago
<html> <style> /* 设置偶数项的背景颜色 */ #content div:nth-child(even) { background-color: #eee; } /* 设置奇数项的背景颜色 */ #content div:nth-child(odd) { background-color: #fff; } </style> <body> <div id="viewport" style="height: 400px; overflow-y: scroll"> <div id="content"></div> </div> </body> <script type="text/javascript"> const viewport = document.getElementById('viewport'); const content = document.getElementById('content'); const itemCount = 100; // 列表项的总数 const itemHeight = 50; // 列表项的高度 const viewportHeight = viewport.offsetHeight; // 视口的高度 const visibleCount = Math.ceil(viewportHeight / itemHeight); // 可见项的数量 const totalHeight = itemCount * itemHeight; // 列表的总高度 // const totalHeight = visibleCount *2 ; // 设置容器的高度 content.style.height = `${totalHeight}px`; const update = () => { const scrollTop = viewport.scrollTop; const startIndex = Math.floor(scrollTop / itemHeight); const endIndex = Math.min(startIndex + visibleCount, itemCount); const items = []; // content.style.paddingTop = `${scrollTop}px`; let tansY = startIndex * itemHeight; // 渲染可见项 for (let i = startIndex; i < endIndex+100; i++) { const item = document.createElement('div'); item.innerText = `Item ${i}`; item.style.height = `${itemHeight}px`; item.style.transform = `translateY(${tansY}px)`; // 设置垂直偏移量 items.push(item); } // 使用 requestAnimationFrame() 延迟渲染新的可见项 window.requestAnimationFrame(() => { content.innerHTML = ''; content.append(...items); }); } update() // 监听滚动事件 viewport.addEventListener('scroll', update); </script> </html>
基于基础的虚拟列表,可以引深问题有 1、实现上下缓冲区 2、item高度不一致时的实现 3、自定义滚动条实现