如果有不足可以补充,虚拟列表是只展示窗口的数据,避免请求过多数据造成卡顿,以下是简单实现虚拟列表的方式
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.scroll_outer {
height: 500px;
overflow: auto;
border: 1px black solid
}
</style>
</head>
<body>
<div class="scroll_outer">
<div class="inner_content"></div>
</div>
<script>
const scrollDiv = document.querySelector('.scroll_outer');
// 滚动容器的高度
const height = scrollDiv.clientHeight
// 设置每一项的高度
const itemHeight = 60
// 生成数据
const initData = () => {
return new Array(100).fill(0).map((_, index) => {
return {
content: `我是${index}`,
color: index % 2 == 0 ? 'red' : 'blue',
height: itemHeight
}
})
}
const data = initData()
// 所有高度
const allHeight = data.length * itemHeight
const handleScroll = () => {
const scrollTop = scrollDiv.scrollTop
//展示窗口===== 开始数据索引
const startIndex = Math.floor(scrollTop / itemHeight)
//展示窗口===== 结束数据索引
const endIndex = Math.ceil(height / itemHeight) + startIndex
// 展示在窗口的数据
const showData = data.slice(startIndex, endIndex + 1)
const innerContent = document.querySelector('.inner_content')
// 把之前的数据情空
innerContent.innerHTML = ''
// 展示数据
showData.forEach((item, index) => {
const itemDiv = document.createElement('div')
itemDiv.innerHTML = item.content
itemDiv.setAttribute('style', `height: ${item.height}px;background: ${item.color}`)
innerContent.appendChild(itemDiv)
})
// 加上padding====保证所有数据出现在视口内
const paddingTOp = startIndex * itemHeight
const paddingBottom = (data.length - endIndex) * itemHeight
innerContent.setAttribute('style', `padding-top: ${paddingTOp}px;padding-bottom: ${paddingBottom}px`)
}
handleScroll()
// 监听滚动事件,不断更新展示数据
scrollDiv.addEventListener('scroll', handleScroll)
</script>
</body>
</html>