虛擬列表使用的場景
虛擬列表是對長列表對一種優(yōu)化手段劫侧,對于一些業(yè)務場景,要展示對列表很長葵礼,同時不能使用分頁對方式,如果一次性把數(shù)據(jù)全部渲染到頁面并鸵,會造成瀏覽器卡死到現(xiàn)象鸳粉,因為dom渲染時間變長,js和瀏覽器渲染共用一個線程园担,用戶操作不能夠及時響應届谈,造成瀏覽器假死現(xiàn)象枯夜。
實現(xiàn)思路
- 滾動容器元素,固定到高度 (scroll-wrap)
- 滾動元素艰山, 根據(jù)總數(shù)據(jù)量及其子元素到高度 計算滾動元素總高度(ul)
- 可是區(qū)域湖雹,就是要渲染的滾動元素的子元素(li),根據(jù)滾動容器高度曙搬,計算要展示的子元素條數(shù)摔吏, 設置滾動元素中 子元素的 startIndex endIndex
在滾動的時候,獲取滾動容器的 scrollTop, 計算已經隱藏的子元素個數(shù)纵装,并設置滾動元素的padding-top, 監(jiān)聽元素的滾動事件征讲,修改startIndex endIndex, 對總數(shù)據(jù) 進行截取 , 如下:
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>
以上就是一個虛擬列表的簡單實現(xiàn)。