<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8" />
<title>前端虚拟列表</title>
<style type="text/css" rel="stylesheet">
.content {
background-color: rgb(250, 172, 94);
overflow: auto;
padding: 0 20px;
width: 100vw;
height: 50vh;
box-sizing: border-box;
}
.target {
height: 100%;
box-sizing: border-box;
}
</style>
</head>
<body>
<div class="content">
<ul class="target"></ul>
</div>
<div class="loading"></div>
</body>
<script>
let loading = false
let datalength = 20 //每页显示数据
let data = [] //总共的1000条数据,数组存放
let showdata = [] //要去渲染的n条数据,数组存放
let itemHeight = "50"
let topdistance = 0 //记录偏移量
let first //首条数据的索引
let end //尾条数据索引
for (let i = 0; i < 20; i++) {
data.push(i)
}
let div = document.querySelector(".content")
let ul = document.querySelector("ul")
let load = document.querySelector(".loading")
//首屏渲染数据
myscroll()
// 使用防抖函数,降低性能开销,但是会存在抖动问题
// div.onscroll = debounce(myscroll, 50)
// 不使用防抖函数
div.onscroll = myscroll
// 防抖函数
function debounce(fn, delay) {
let timer = null
return function (...args) {
if (timer) {
clearTimeout(timer)
}
timer = setTimeout(() => {
fn.apply(this, args)
}, delay)
}
}
function onScrollDown() {
if (loading) return
return new Promise(resolve => {
loading = true
load.innerHTML = "模拟请求数据 数据加载中..."
setTimeout(() => {
let max = data[data.length - 1]
for (let i = max + 1; i < max + 20; i++) {
data.push(i)
}
loading = false
load.innerHTML = ""
resolve()
}, 2000)
})
}
async function myscroll(e) {
if (
end >= data.length - 1 &&
e &&
e.target.scrollHeight - e.target.scrollTop - e.target.clientHeight <=
itemHeight
) {
//触底时进行操作
await onScrollDown()
}
//手动设置偏移量
topdistance = e ? e.target.scrollTop : 0
//将偏移量赋值给paddingTop,注意上述css盒模型如果不设置一下的话,会导致滚轮一直下滑,ul的高度会被无限拉长
ul.style.paddingTop = topdistance - (topdistance % itemHeight) + "px"
//根据偏移量判断该从哪里截取
let index = Math.floor(topdistance / itemHeight)
first = index
end = index + datalength
//对原生数据进行截取
showdata = data.slice(first, end)
//下面操作dom节点进行渲染
const dom = document.createDocumentFragment()
let li = null
showdata.map(item => {
li = document.createElement("li")
li.style.height = itemHeight + "px"
li.style.fontSize = "30px"
li.innerHTML = item
dom.appendChild(li)
})
//每次渲染之前清空内容
ul.innerHTML = ""
ul.appendChild(dom)
}
</script>
</html>
前端性能优化之:虚拟列表+网络请求数据
最后编辑于 :
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。
推荐阅读更多精彩内容
- 问题 在前端页面数据查询时,可能会遇到实时搜索的需求。在实时搜索时,就可能存在一个问题,就是后一次请求数据被前一次...
- NSString *p = @"/Users/mac/Desktop/九宫格图片处理";NSString *ps ...
- 遇到了个奇葩问题,xcode-8.0请求数据返回JSON数据只打印了一部分,跟后台确认了好几次。人家不背锅,测试A...
- 一、vue-resource vue官方原生库 1.安装 $ npm install vue-resource -...
- 在使用okhttp3中遇到一个问题:CLEARTEXT communication to XX not permi...