虚拟列表使用的场景
虚拟列表是对长列表对一种优化手段,对于一些业务场景,要展示对列表很长,同时不能使用分页对方式,如果一次性把数据全部渲染到页面,会造成浏览器卡死到现象,因为dom渲染时间变长,js和浏览器渲染共用一个线程,用户操作不能够及时响应,造成浏览器假死现象。
实现思路
- 滚动容器元素,固定到高度 (scroll-wrap)
- 滚动元素, 根据总数据量及其子元素到高度 计算滚动元素总高度(ul)
- 可是区域,就是要渲染的滚动元素的子元素(li),根据滚动容器高度,计算要展示的子元素条数, 设置滚动元素中 子元素的 startIndex endIndex
在滚动的时候,获取滚动容器的 scrollTop, 计算已经隐藏的子元素个数,并设置滚动元素的padding-top, 监听元素的滚动事件,修改startIndex endIndex, 对总数据 进行截取 , 如下:
let count = 1000;
let startIndex = 0;
let endIndex = 11;
let arr = [];
for(let i = 0; i < count; i++) {
arr.push('<li>' + i + '</li>');
}
let ul = document.getElementById('ul');
ul.style.height = 1000 * 50 + 'px';
let visblearr = arr.slice(startIndex, endIndex);
ul.innerHTML = visblearr.join(' ');
function render(wrap) {
const scrollTop = wrap.scrollTop
ul.innerHTML = '';
let topIndex = Math.floor(scrollTop / 50);
ul.style.paddingTop = topIndex * 50 + 'px';
startIndex = topIndex;
endIndex = startIndex + 11;
let visblearr = arr.slice(startIndex, endIndex);
ul.innerHTML = visblearr.join(' ');
}
document.getElementsByClassName('scroll-wrap')[0].addEventListener('scroll', function (e) {
render(this)
})
<style>
.scroll-wrap {
height: 500px;
overflow: auto;
border: 1px solid #000;
}
ul {
margin: 0;
box-sizing: border-box;
}
li {
height: 50px;
}
</style>
<div class='scroll-wrap'>
<ul id='ul'></ul>
</div>
以上就是一个虚拟列表的简单实现。