虚拟列表渲染
*{
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)