水一个简单的虚拟列表
虚拟列表就是通过几个列表项将无数数据依次以列表形式展现出来
在这里我通过设置一个容器的高度将主要容器撑起来,它的高度由单个列表项高度乘以数据长度得来;撑起主要容器的作用主要是模拟普通列表的滚动条
主要容器滚动时,下移列表,使得列表一直在视窗内;具体的距离计算方法和列表项内容更新方法在代码里有,也就一句代码,这是我目前能找到和想到的简单的方法
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style type="text/css">
* {
margin: 0px;
padding: 0px;
}
body {
width: 100vw;
height: 100vh;
display: flex;
align-items: center;
justify-content: center;
background-color: #f3f3f3;
}
.main {
width: 800px;
height: 500px;
border-radius: 5px;
overflow-y: auto;
border: 3px solid #008CD6;
}
.container {
width: 100%;
}
ul {
width: 100%;
height:auto;
/* 设置固定值会撑起容器 */
/* 滚动时它会下移,使用如果它撑起容器 ,那么会出现空白 */
max-height: 600px;
list-style-type: none;
}
ul>li {
width: 100%;
height: 40px;
line-height: 40px;
text-align: center;
font-weight: bold;
}
</style>
</head>
<body>
<div class="main">
<div class="container">
<ul></ul>
</div>
</div>
<script type="text/javascript">
const mainDiv = document.querySelector('.main'),
container = document.querySelector('.container'),
ul = document.querySelector('ul');
const showList = new Array();
for (let i = 0; i < 1000; i++) {
const li = document.createElement("li");
li.innerText = `第${i+1}个li标签,打开控制台进入“元素”选项以查看运行效果`;
if (i % 2 === 0) {
li.style.cssText = "background-color: #008CD6;color:#f3f3f3;";
}
showList.push(li);
}
container.style.height = `${1000*40}px`;
function showData(arr) {
ul.innerHTML = "";
for (let itme of arr) {
ul.appendChild(itme);
}
}
showData(showList.slice(0, 15));
function render(e) {
const TranslateY = e.srcElement.scrollTop;
startData = Math.floor(TranslateY / 40); //向下取整
endData = startData + 15;
ul.style = `transform:translateY(${TranslateY - (TranslateY % 40)}px)`;
//也可以,效果一样
// ul.style = `transform:translateY(${Math.floor(TranslateY/40)*40}px)`;
//也可以,但很生硬;而且因为上面计算方法问题,最后一个没能完全展示
// ul.style = `transform:translateY(${TranslateY}px)`;
showData(showList.slice(startData, endData));
}
mainDiv.addEventListener('scroll', render);
</script>
</body>
</html>