最近在做一个PC端的项目,要求是在滑动到页面的底部的时候就动态的加载下一页的数据,代码实现思路如下:
首先,我们需要知道浏览器中有三个高度,分别是屏幕高度(outerHeight),文档容器高度(innerHeight)以及屏幕滚动高度(scrollHeight),他们的计算方法如下
scrollTop = document.documentElement.scrollTop // 屏幕滚动高度 innerHeight = document.querySelector('#app').clientHeight // 容器高度 outerHeight = document.documentElement.clientHeight // 屏幕高度
我们分析可知,要想实现那个效果,我们需要让屏幕的滚动高度+屏幕的高度 >= 容器的高度,满足这个条件的话我们就可以说他是到达底部了,代码如下
mounted(){ window.addEventListener('scroll',this.handleScroll) } // 这里解释一下,之所以写在mounted而不写在created里面,是因为created的时候有可能页面dom元素还没有加载完成,所以事件有可能绑不上。
这里会有一个小bug,也是我在项目中碰到的,就是如果我们发现你监听了scroll事件,但是在你滚动的时候却没有触发后面的函数,这时候我们可以去检查一下页面元素中
是不是设置了overflow属性(如果你用的是前端框架的话,你有可能需要去检查一下他的父级组件里面有没有设置overflow的属性),因为如果你设置了这个属性的话,他就会
阻断scroll事件的监听。
然后我们就可以来进行我们的触底判断,并且进行请求数据的操作了:
handleScroll(){ if(this.isAtBottom) return; let scrollTop = document.documentElement.scrollTop // 屏幕滚动高度 let innerHeight = document.querySelector('#app').clientHeight // 容器高度 let outerHeight = document.documentElement.clientHeight // 屏幕高度 if (outerHeight + scrollTop >= innerHeight+10) { // getData() 这里就可以去请求数据了 } }
做到这里,其实我们的触底效果已经实现了,但是在实际运行中,我们可能会发现他有可能在到达底部的时候有可能会触发好几次请求数据,如果我们是从接口拿的数据的
话,我们就会发现,他有可能回去疯狂的请求接口,然后导致数据的大量重复,然后我发现,是因为屏幕高度和容器高度在一定时间内(重新请求数据前)是不会改变的,但是滚
动高度+屏幕高度 >= 容器高度的时候,满足条件的滚动高度可能存在一个区间,所以就导致了触发多次的问题。那么怎么去解决这个问题嘞?于是我用到了防抖,关于防抖以及节
流的相关内容,大家可以参考https://www.jianshu.com/p/c8b86b09daf0,这个里面介绍的很详细,下面说一下我的实现方法。代码修改如下:
mounted(){ window.addEventListener('scroll',this.debounce(this.handleScroll,500)) }, methods:{ debounce(fn, wait) { //节流方法 var timeout = null; // 初始化定时器 return function() { if(timeout !== null) clearTimeout(timeout); // 如果scroll方法反复触发,则清空定时器 timeout = setTimeout(fn, wait); // 如果方法没有反复触发,那么就调用我们判断滚动的方法,然后去调用数据,他就只会请求一次了 } } }
以上,就是关于触底请求数据的所有信息了,希望对大家有帮助。