上一篇文章讲了在 js 中如何实现图片懒加载,这一篇则讲解,如何实现滑动到底部加载更多。
跟图片懒加载一样,滑动到底部加载更多,一般传统方式是监听 scroll
事件,现在有更简单的方式为 IntersectionObserver
;
传统方式(scroll
)
通过监听滚动容器的 scroll
事件,每次滑动后,判断是否已经滑动到了底部,如果已经滑动到了底部,则触发加载事件。
let timer = -1 // 函数防抖
let $scroll = document.querySelector('#scroll') // 滑动的容器
// 为滑动的容器添加 scroll 事件
$scroll.addEventListener('scroll', function () {
clearTimeout(timer)
timer = setTimeout(() => {
// 滚动所在容器的可视高度
let height = $scroll.getBoundingClientRect().height
let top = $scroll.scrollTop // 滚动的距离
let scrollHeight = $scroll.scrollHeight // 滚动容器的实际高度
if (scrollHeight - top - height <= 60) {
// 处于滑动临界值内,处理加载更多
loadmore() // 加载更多
}
}, 150) // 避免过于频繁,防抖
})
跟图片懒加载一样,由于频繁的触发 scroll
的性能影响问题,使用 IntersectionObserver
能够解决这个问题。
IntersectionObserver
要使用 IntersectionObserver
来判断是否滑动到底部,我们就需要在列表的底部,添加一个元素用来占位,同时我们可以给这个元素加一个提示,这样我们既能通过代码判断是否滑动到底部,同时又给出了友好的提示。
let $loadmoreTip = document.querySelector('.loadmore-tip')
// 构建观察器
let observer = new IntersectionObserver((entries) => {
for (let entry of entries) {
/*
* 检测节点是否可见,可以通过 isIntersecting 验证,布尔值
* 如果目标元素与交叉区域观察者对象(intersection observer)的根相交,返回 true
* 此时描述了变换到交叉时的状态;
* 如果返回 false, 那么可以由此判断,变换是从交叉状态到非交叉状态.
* 同时也可以根据 intersectionRatio 验证
* intersectionRatio:目标元素的可见比例
* 即 intersectionRect 占 boundingClientRect 的比例
* 完全可见时为1,完全不可见时小于等于0
* 如果不可见,就返回:
* if (entry.intersectionRatio <= 0) return;
*/
if (entry.isIntersecting === true) { // 检测节点是否可见
// 处于交叉可见状态
loadmore()
}
}
}, { threshold: 0.6 });
// 往观察器列表注册观察元素
observer.observe($loadmoreTip);