之前H5中实现列表滚动到底部加载下一页数据,需要监听滚动事件,获取页面滚动的垂直距离、页面的总高度,处理浏览器兼容,计算是否滚动到底部,做节流等,这一套处理下来非常的麻烦。现如今随着技术的进步,浏览器推出了多种 观察器,让我们可以更便捷、高效的收集页面与元素的信息。比如 监听元素与视窗交叉状态 的观察器:IntersectionObserver(交叉观察器)
就可以实现无限滚动和图片懒加载。
在MDN文档上可以看IntersectionObserver的详细介绍Intersection Observer API。
实现无限滚动
实现一个无限滚动的步骤如下:
- 创建
IntersectionObserver
实例,并指定观察的目标元素,通常是页面底部的加载中占位符元素 - 在回调函数中,判断目标元素是否进入视窗。
- 若目标元素进入视窗,触发数据加载的操作,并更新页面内容。
// 回调
// entries为一个 IntersectionObserverEntry 对象的数组,
// 每个被触发的阈值,都或多或少与指定阈值有偏差。
const cb = (entries) => {
entries.forEach((entry) => {
// isIntersecting是一个Boolean值,判断目标元素当前是否可见,
// 返回一个布尔值,下列两种操作均会触发callback:
// 1. 如果目标元素出现在可视区,返回true。
// 2. 如果从可视区消失,返回false
if (entry.isIntersecting) {
getList({ page, pageSize ... }) // 触发数据加载操作
}
})
}
// 创建观察实例
const observer = new IntersectionObserver(cb)
// 获取占位符元素
const loading = document.querySelector('.loading')
// 观察加载中占位符元素
observer.observe(loading)
用 IntersectionObserver
实现无限滚动,可以平滑的加载体验,避免频繁的触发滚动事件,只在需要底部的加载中占位符元素出现时才进行相应列表请求,减少了无效的请求消耗。
实现懒加载
思路是在不可视区域内的图片资源延迟加载,在元素进入视窗时进行加载。
const imgs = [...document.querySelectorAll('img')]
const cb = (entries) => {
entries.forEach(item => {
// isIntersecting是一个Boolean值,判断目标元素当前是否可见
if (item.isIntersecting) {
item.target.src = item.target.dataset.src
// 图片加载后即停止监听该元素
observer.unobserve(item.target)
}
})
}
const options = {
root: document.querySelector('.root'),
threshold: 0
}
const observer = new IntersectionObserver(cb, options)
// observe遍历监听所有img节点
imgs.forEach(img => observer.observe(img))
仅作记录项目经历,参考文章地址: