Vue混入mixins滚动触底的方法
前言
在app端常常看到类似加载数据的动画,接下来我们来实现滚动触底加载动画提示,以及如何复用这些逻辑。
如何判断滚动触底
来看下几张图:
情况一:
当文档高度还为超过可视区域高度时,不存在滚动,所以也没有滚动触底
当文档高度超过可视区域的高度时,还有剩余的文档没有滚动完,也就是说可视区域高度+滚动高度<文档高度,此时没有达到滚动触底的条件
文档高度大于可视区域,并且滚动到文档底部,也就是说可视区域高度+滚动高度=文档高度
经过上面三种情况的分析,我们需要拿到可视区域的高度,滚动高度,文档高度这三个变量来进行比较。
可视区域的高度
functiongetWindowHeight(){
returndocument.documentElement.clientHeight;
}
滚动高度
对有doctype申明的页面使用document.documentElement.scrollTop,safari特例独行:使用window.pageYOffset
functiongetScrollHeight(){
returnMath.max(document.documentElement.scrollTop,window.pageYOffset||0)
}
文档高度
functiongetDocumentTop(){
returndocument.documentElement.offsetHeight;
}
代码实现
触底打印
codepen触底打印demo
通过监听滚动事件来判断可视区域,滚动高度,文档高度的关系,实现最基础的触底加载
{{item}}
优化和复用滚动事件逻辑
将滚动逻辑抽取成mixins放在scroll.js中。优化功能点如下:
- 增加触底距离
- 滚动事件监听事件节流
- 添加触底动画,并将UI样式一起封装在scroll.js中
模拟请求事件
为了模拟请求数据,封装了一个Promise一秒后返回结果
methods:{
//返回一个promise,用于请求服务端数据
findDataList(){
letlist=this.list
letlast=list[list.length-1]
returnnewPromise((resolve)=>{
//模拟服务端数据
letnewList=Array.from(Array(10),(item,index)=>index+last+1)
setTimeout(()=>{
resolve(newList)
},1000);
})
}
}
滚动事件监听
滚动事件触发,判断当前是否触底,触底了以后去执行loadMore发起请求拿取服务端的数据
created(){
letfn=throttle(()=>{
letisOver=(getScrollHeight()+getWindowHeight())>=(getDocumentTop()-MIN_INSTANCE)
//触底时进行数据加载
if(isOver){
//创建加载组件
this.loadMore&&this.loadMore()
}
},DEALY_TIME)
window.addEventListener('scroll',fn)
},
添加触底动画
因为我们是将逻辑抽离在mixins中,为了把触底动画也集成在里面使用Vue.extend()来实现编程式插入UI样式的方法。
首先定义好loading组件的样式
{{message}}