<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>虚拟列表实现</title>
<style type="text/css">
.section{
height: 50vh;
width: 50%;
margin: 25vh auto;
background-color: gainsboro;
overflow: auto;
}
.list{
height: auto;
width: 80%;
margin: auto;
background-color: antiquewhite;
}
html ,body, section{
margin: 0px;
padding: 0px;
}
</style>
</head>
<body>
<div class="section">
<div class="list"></div>
</div>
<script>
window.onload = function(){
//真实列表数据
let itemListData = initListData();
//列表容器
let section = document.querySelector(".section");
//列表高度
let sectionHeight = getNodeHeight(section);
//列表子项样式
let listStyle = {
height: "20px",
}
//列表子项高度
let listItemHeight = 20;
//可以容纳多少列表子项
let canVisible = Math.ceil(sectionHeight/listItemHeight) +1;
const proxyItemList = createListProxy(listStyle);
initScrollEvent(section, canVisible, listItemHeight, itemListData, listItemHeight, proxyItemList);
// console.log(sectionHeight, sectionHeight, canVisible);
for(let i = 0; i < canVisible; i++){
proxyItemList.push(i);
}
}
//初始化列表数据
function initListData(){
let total = 10000;
let itemData = [];
for(let i = 0; i < total; i++){
itemData.push(i);
}
return itemData;
}
//初始化容器滚动事件
function initScrollEvent(node, canVisible, itemHeight,itemListData, listItemHeight,proxyItemList){
let list = document.querySelector(".list");
node.onscroll = function(event){
//获取到顶部高度
let scrollTop = event.target.scrollTop;
//确定起始索引
let startIndex = Math.floor(scrollTop / itemHeight);
//确定结束索引
let endIndex = startIndex + canVisible;
//确定展示数据
let showData = itemListData.slice(startIndex, endIndex);
console.log(startIndex, endIndex, showData);
proxyItemList.length = 0;
for(let data of showData){
proxyItemList.push(data);
}
let startOffset = scrollTop - (scrollTop % listItemHeight);
// let startOffset = scrollTop;
console.log(startOffset)
list.style.transform = `translate3d(0,${startOffset}px,0)`
// console.log(event.target.scrollTop);
}
}
function createListProxy(listStyle){
//列表数据
let itemList = [];
//列表容器
let list = document.querySelector(".list");
const handleItemList = {
set(target, propety, value){
// console.log(target,propety, value);
if(propety == "length" && value != 0){
for(let i = list.childElementCount - 1; i >= 0; i--){
list.removeChild(list.children[i]);
}
for(let i = 0; i < target.length; i++){
if(target[i] != null){
let item = document.createElement("div");
item.innerText = "I am " + target[i];
setStyle(item, listStyle);
list.appendChild(item);
}
}
}else{
for(let i = list.childElementCount - 1; i >= 0; i--){
list.removeChild(list.children[i]);
}
}
return Reflect.set(...arguments);
}
}
return new Proxy(itemList, handleItemList);
}
function setStyle(node,obj){
for(let key of Object.keys(obj)){
node.style[key] = obj[key];
}
}
function getNodeHeight(node){
return window.getComputedStyle(node, null).height.replace(/[^\d.]/g, "");
}
function computedItemHeight(listStyle){
let div = document.createElement("div");
setStyle(div, listStyle);
let style = window.getComputedStyle(div, null)
let total = style.marginTop.replace(/[^\d.]/g, "")
+ style.marginBottom.replace(/[^\d.]/g, "")
+ style.paddingTop.replace(/[^\d.]/g, "")
+ style.paddingBottom.replace(/[^\d.]/g, "")
+ style.height.replace(/[^\d.]/g, "");
return total;
}
</script>
</body>
</html>
<!-- <!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>虚拟列表实现</title>
</head>
<body>
<button id="button">button</button><br>
<ul id="container"></ul>
<script>
let button = document.querySelector("#button");
button.onclick = function(){
let now = Date.now();
let total = 10000;
let ul = document.querySelector("ul");
for(let i = 0; i < total; i++){
let li = document.createElement("li");
ul.appendChild(li);
}
console.log(Date.now() - now);
setTimeout(()=>{
console.log(Date.now() - now)
}, 0)
}
</script>
</body>
</html> -->
长列表优化方案,虚拟列表
猜你喜欢
转载自blog.csdn.net/m0_57033755/article/details/131760765
今日推荐
周排行