使用场景及原理:
场景:接口一次性返回所有数据,数据量特别庞大,会导致页面DOM元素过多,页面就会变得很卡,此时可以使用虚拟列表来解决
原理:只在可视区域内展示数据
css部分:
.box {
width: 500px;
height: 800px;
position: relative;
box-sizing: border-box;
overflow-y: scroll;
background-color: blanchedalmond;
}
.list {
box-sizing: border-box;
}
.item {
height: 30px;
text-align: center;
line-height: 30px;
color: #000;
background-color: cadetblue;
}
html部分:
<div class="box" id="box">
<div class="list" id="list"></div>
</div>
js部分:
// 数据
let list = []
for (let i = 0; i < 100000; i++) {
list.push(i + 1)
}
// dom部分
const BOX = document.getElementById('box'),
LIST = document.getElementById('list'),
NUM = Math.floor(BOX.clientHeight / 30) + 2
// 开始结束索引(渲染这个索引区域的数据)
let startIndex = 0,
endIndex = NUM
LIST.style.height = list.length * 30 + 'px' // 设置列表高度
setData(startIndex, endIndex) // 渲染初始数据
BOX.addEventListener('scroll', e => handleBoxScroll(e)) // 添加滚动事件
function handleBoxScroll(e) {
startIndex = Math.floor(e.target.scrollTop / 30) // 开始索引 = 滚动距离 / 每一项的高度
endIndex = NUM + startIndex // 结束索引 = 初始结束索引 + 新的开始索引
setBoxPadding(startIndex) // 设置列表paddingTop
setData(startIndex, endIndex) // 渲染数据
}
// 设置可视区域数据
function setData(startIndex, endIndex) {
let fragment = document.createDocumentFragment() // 创建文档碎片
let showList = list.slice(startIndex, endIndex) // 取出要渲染的数据
for (let i = 0; i < showList.length; i++) { // 循环添加节点
let el = document.createElement('div')
el.className = 'item'
el.innerText = `列表项${showList[i]}`
fragment.appendChild(el)
}
LIST.innerHTML = '' // 清空子节点
LIST.appendChild(fragment) // 一次性渲染到视图上
}
// 设置容器内边距
function setBoxPadding(start) {
LIST.style.paddingTop = start * 30 + 'px'
}
以上就是本文所有内容,第一次写文章,有不对的地方欢迎大家提出,非常感谢!!!