用IntersectionObserver实现无限滚动和图片懒加载

之前H5中实现列表滚动到底部加载下一页数据,需要监听滚动事件,获取页面滚动的垂直距离、页面的总高度,处理浏览器兼容,计算是否滚动到底部,做节流等,这一套处理下来非常的麻烦。现如今随着技术的进步,浏览器推出了多种 观察器 ,让我们可以更便捷、高效的收集页面与元素的信息。比如 监听元素与视窗交叉状态 的观察器:IntersectionObserver(交叉观察器) 就可以实现无限滚动和图片懒加载。

在MDN文档上可以看IntersectionObserver的详细介绍Intersection Observer API。

实现无限滚动

实现一个无限滚动的步骤如下:

  • 创建 IntersectionObserver 实例,并指定观察的目标元素,通常是页面底部的加载中占位符元素
  • 在回调函数中,判断目标元素是否进入视窗。
  • 若目标元素进入视窗,触发数据加载的操作,并更新页面内容。
js 复制代码
// 回调
// 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 实现无限滚动,可以平滑的加载体验,避免频繁的触发滚动事件,只在需要底部的加载中占位符元素出现时才进行相应列表请求,减少了无效的请求消耗。

实现懒加载

思路是在不可视区域内的图片资源延迟加载,在元素进入视窗时进行加载。

js 复制代码
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))

仅作记录项目经历,参考文章地址:

用IntersectionObserver实现无限滚动和图片懒加载

相关推荐
lerhxx7 小时前
AI 应用如何高效优雅地恢复中断?—— "连接解耦 + 状态持久化"
前端·javascript
mantou1328 小时前
我给 AI Agent 做了个「油猴」:让 Claude Code / Codex 直接用你已登录的浏览器
前端·javascript·后端
默_笙8 小时前
🍕 一个主编、三个工种、两本手册:搭一支 AI 调研队
前端·javascript
CappuccinoRose9 小时前
FormData数据处理
开发语言·前端·javascript·表单数据
飘尘10 小时前
SVG和Canvas,前端里的两支“画笔”,用的时候怎么选择?
前端·javascript·面试
Sand(ContextGate)14 小时前
Python Agent 测试实战:测试与评估,让 Agent 像传统软件一样可交付
前端·javascript·python·microsoft·ai
码艺-Alimjan14 小时前
Tauri 网站To桌面应用实战总结
前端·javascript·vue
liangshanbo121516 小时前
请求拦截器相关面试题
java·前端·javascript
liangshanbo121516 小时前
React面试题:Hooks 为什么不能在分支和循环里面写?
前端·javascript·react.js
西红柿炖牛腩35416 小时前
GLB 转 OBJ/PLY 后体积没变?3D 模型不减面变小靠什么
前端·javascript·3d