滚动下滑请求和vue循环v-for延迟展示dom逻辑
为了方便,案列都使用vue做演示
滚动加载
逻辑:计算数据滚动区高度,计算当前滚动条离顶部高度,计算数据可视区域高度,滚动区域=离顶部高度+可视高度即到底部了。
注意:如果不提供手动加载按钮,就需要根据数据调整第一页数据填充数据区域高度使它出现滚动条。
代码示例
html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<title>Title</title>
</head>
<body>
<div id="v">
<div v-for="(item,i) of list" :key="i">
<h5>{{item.id}}</h5>
<h3>{{item.date}}</h3>
</div>
</div>
<script src="https://cdn.bootcss.com/vue/2.6.8/vue.min.js"></script>
<script>
new Vue({
el: '#v',
data: {
list: [] // 存放数据
},
mounted() {
// 获取首页数据
this.getList()
// 绑定滚动事件
window.addEventListener('scroll', () => this.initList())
},
methods: {
getList() {
// 模拟数据
for (let i = 0; i < 20; i++) {
this.list.push({
id: Math.random(),
date: new Date()
})
}
},
initList() {
// 滚动条移动长度
let sTop =
pageYOffset ||
document.documentElement.scrollTop ||
document.body.scrollTop
// 当前页面总长度
let sHeight =
document.documentElement.scrollHeight ||
document.body.scrollHeight
// 可见的页面长度
let ch = document.documentElement.clientHeight
// 滑到了最下面接近30px附近,获取下一页数据,防止计算不精确
if (sTop + ch + 30 >= sHeight) {
this.getList()
}
}
}
})
</script>
</body>
</html>
延迟展示
vue循环不好控制中间过程,差不多的意思也就是控制不了循环的生命周期。
逻辑:多数时候是要使用动画展示,这里分享我使用简单粗暴的逻辑,先都vue将dom渲染完毕,但全部给隐藏。
注意:display和visibility是有区别的,display在页面上不会为dom占据自己那份空间,而visibility则会,所以在结合滚动加载的时候,需要使用visibility,这里显示无所谓。
代码示例
这里使用一下动画库animate.css
html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<title>Title</title>
<link
href="https://cdn.bootcss.com/animate.css/3.7.0/animate.min.css"
rel="stylesheet"
/>
<style>
.no-ani {
visibility: hidden;
}
</style>
</head>
<body>
<div id="v">
<div
class="no-ani animated"
ani="zoomIn"
v-for="(item,i) of list"
:key="i"
>
<h5>{{item.id}}</h5>
<h3>{{item.date}}</h3>
</div>
</div>
<script src="https://cdn.bootcss.com/vue/2.6.8/vue.min.js"></script>
<script>
new Vue({
el: '#v',
data: {
list: [] // 存放数据
},
mounted() {
// 获取首页数据
this.getList()
// 显示一下第一页
// 没有使用到promise,所以做一下延迟,也可以利用钩子函数保证dom挂载完成
setTimeout(() => {
this.initList()
}, 500)
// 绑定滚动事件
window.addEventListener('scroll', () => this.initList())
},
methods: {
getList() {
// 模拟数据
for (let i = 0; i < 20; i++) {
this.list.push({
id: Math.random(),
date: new Date()
})
}
},
initList() {
// 滚动条移动长度
let sTop =
pageYOffset ||
document.documentElement.scrollTop ||
document.body.scrollTop
// 当前页面总长度
let sHeight =
document.documentElement.scrollHeight ||
document.body.scrollHeight
// 可见的页面长度
let ch = document.documentElement.clientHeight
// 滑到了最下面接近30px附近,获取下一页数据,防止计算不精确
if (sTop + ch + 30 >= sHeight) {
this.getList()
}
// 未显示的列表
let domList = document.getElementsByClassName('no-ani')
// 扁你一下隐藏的dom
Array.prototype.slice.apply(domList).forEach((item, i) => {
// 判断该是否组件是否到可视页面
if (sTop + ch > item.offsetTop) {
// 每一个小模块都在上一个模块的基础上多200毫秒显示
setTimeout(() => {
// 删除不显示控制
item.classList.remove('no-ani')
// 添加指定动画
item.classList.add(item.getAttribute('ani'))
// 删除指定属性
item.removeAttribute('ani')
}, 200 * i)
}
})
}
}
})
</script>
</body>
</html>
以上代码都可以直接拷贝运行
![[微笑]](/face/0.gif)
![[嘻嘻]](/face/1.gif)
![[哈哈]](/face/2.gif)
![[可爱]](/face/3.gif)
![[可怜]](/face/4.gif)
![[挖鼻]](/face/5.gif)
![[吃惊]](/face/6.gif)
![[害羞]](/face/7.gif)
![[挤眼]](/face/8.gif)
![[闭嘴]](/face/9.gif)
![[鄙视]](/face/10.gif)
![[爱你]](/face/11.gif)
![[泪]](/face/12.gif)
![[偷笑]](/face/13.gif)
![[亲亲]](/face/14.gif)
![[生病]](/face/15.gif)
![[太开心]](/face/16.gif)
![[白眼]](/face/17.gif)
![[右哼哼]](/face/18.gif)
![[左哼哼]](/face/19.gif)
![[嘘]](/face/20.gif)
![[衰]](/face/21.gif)
![[委屈]](/face/22.gif)
![[吐]](/face/23.gif)
![[哈欠]](/face/24.gif)
![[抱抱]](/face/25.gif)
![[怒]](/face/26.gif)
![[疑问]](/face/27.gif)
![[馋嘴]](/face/28.gif)
![[拜拜]](/face/29.gif)
![[思考]](/face/30.gif)
![[汗]](/face/31.gif)
![[困]](/face/32.gif)
![[睡]](/face/33.gif)
![[钱]](/face/34.gif)
![[失望]](/face/35.gif)
![[酷]](/face/36.gif)
![[色]](/face/37.gif)
![[哼]](/face/38.gif)
![[鼓掌]](/face/39.gif)
![[晕]](/face/40.gif)
![[悲伤]](/face/41.gif)
![[抓狂]](/face/42.gif)
![[黑线]](/face/43.gif)
![[阴险]](/face/44.gif)
![[怒骂]](/face/45.gif)
![[互粉]](/face/46.gif)
![[心]](/face/47.gif)
![[伤心]](/face/48.gif)
![[猪头]](/face/49.gif)
![[熊猫]](/face/50.gif)
![[兔子]](/face/51.gif)
![[ok]](/face/52.gif)
![[耶]](/face/53.gif)
![[good]](/face/54.gif)
![[NO]](/face/55.gif)
![[赞]](/face/56.gif)
![[来]](/face/57.gif)
![[弱]](/face/58.gif)
![[草泥马]](/face/59.gif)
![[神马]](/face/60.gif)
![[囧]](/face/61.gif)
![[浮云]](/face/62.gif)
![[给力]](/face/63.gif)
![[围观]](/face/64.gif)
![[威武]](/face/65.gif)
![[奥特曼]](/face/66.gif)
![[礼物]](/face/67.gif)
![[钟]](/face/68.gif)
![[话筒]](/face/69.gif)
![[蜡烛]](/face/70.gif)
![[蛋糕]](/face/71.gif)