图片懒加载的实现

图片懒加载是一种优化网页性能的技术,它可以延迟加载图片,直到图片进入浏览器的可视区域,从而减少初始加载时的资源消耗,提升页面加载速度。

  • 加载时机data-src 本身不会触发资源的加载,它只是一个数据存储的地方。只有当通过 JavaScript 等方式将 data-src 的值赋给 src 属性时,浏览器才会发起对该资源的请求。
  • src 是标准的 HTML 属性,用于指定资源的来源地址,浏览器会立即加载该资源。
  • data-src 是自定义属性,用于存储自定义数据。

IntersectionObserver

IntersectionObserver 是浏览器提供的一个用于异步观察目标元素与其祖先元素或顶级文档视口(viewport)交叉状态的 API。它在处理懒加载、无限滚动、广告曝光监测等场景中非常有用,下面从几个方面详细介绍它。

基本原理

IntersectionObserver 允许你注册一个回调函数,当目标元素与指定的根元素(默认为浏览器视口)的交集区域发生变化时,这个回调函数会被触发。它采用了一种非阻塞的异步方式,避免了传统通过监听 scrollresize 等事件进行元素可见性检测时可能带来的性能问题。

基本用法

使用 IntersectionObserver 主要有以下几个步骤:

1. 创建 IntersectionObserver 实例

javascript

ini 复制代码
const observer = new IntersectionObserver(callback, options);
  • callback:当目标元素的可见性发生变化时会调用的回调函数,该函数接收两个参数:

    • entries:一个包含所有被观察元素的 IntersectionObserverEntry 对象的数组,每个 IntersectionObserverEntry 对象描述了一个被观察元素的可见性变化信息。
    • observer:当前的 IntersectionObserver 实例。
  • options:一个可选的配置对象,包含以下属性:

    • root:指定根元素,即用于检查目标元素可见性的元素,默认为浏览器视口。
    • rootMargin:根元素的外边距,类似于 CSS 的 margin 属性,用于扩展或缩小根元素的边界框,格式为 "10px 20px 30px 40px"
    • threshold:一个数值或数值数组,定义了一个或多个交叉比例阈值,当目标元素与根元素的交叉比例达到这些阈值时,回调函数会被触发。例如,[0, 0.5, 1] 表示当目标元素的可见比例为 0%、50%、100% 时都会触发回调。
2. 观察目标元素
ini 复制代码
const target = document.getElementById('target-element');
observer.observe(target);

通过 observe 方法可以让 IntersectionObserver 开始观察指定的目标元素。

3. 停止观察目标元素
ini 复制代码
observer.unobserve(target);

使用 unobserve 方法可以停止对某个目标元素的观察。

原生 JavaScript 实现

通过监听窗口滚动事件和 IntersectionObserver API 来实现图片懒加载。

  1. HTML 部分 :为需要懒加载的图片添加 lazyload 类,并将真实的图片地址存储在 data-src 属性中,src 属性设置为一个占位图片(这里使用了一个透明的 GIF 图片)。

  2. JavaScript 部分

    • IntersectionObserver :如果浏览器支持 IntersectionObserver,则使用它来监听图片是否进入可视区域。当图片进入可视区域时,将 data-src 的值赋给 src 属性,并停止观察该图片。
    • 降级处理 :如果浏览器不支持 IntersectionObserver,则监听 scrollresizeorientationChange 事件,在事件触发时检查图片是否进入可视区域
xml 复制代码
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>IntersectionObserver 图片懒加载示例</title>
</head>

<body>
    <img class="lazy" data-src="https://picsum.photos/200/300" src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" alt="Lazy Loaded Image">
    <img class="lazy" data-src="https://picsum.photos/200/300?random=2" src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" alt="Lazy Loaded Image">

    <script>
        const lazyImages = document.querySelectorAll('img.lazy');

        const observer = new IntersectionObserver((entries, observer) => {
            entries.forEach((entry) => {
                if (entry.isIntersecting) {
                    const img = entry.target;
                    img.src = img.dataset.src;
                    img.classList.remove('lazy');
                    observer.unobserve(img);
                }
            });
        });

        lazyImages.forEach((image) => {
            observer.observe(image);
        });
    </script>
</body>

</html>

代码解释

  • 首先,获取所有带有 lazy 类的图片元素。
  • 然后,创建一个 IntersectionObserver 实例,当目标元素进入视口(isIntersectingtrue)时,将 data-src 属性的值赋给 src 属性,移除 lazy 类,并停止对该元素的观察。
  • 最后,对每个图片元素调用 observe 方法,开始观察它们的可见性变化。

兼容性

IntersectionObserver 已经得到了大多数现代浏览器的支持,但在一些旧版本的浏览器中可能不支持。在使用时,可以结合一些兼容性处理,例如使用 IntersectionObserver 进行懒加载,同时为不支持的浏览器提供降级方案(如监听 scroll 事件)。

相关推荐
加班是不可能的,除非双倍日工资3 小时前
css预编译器实现星空背景图
前端·css·vue3
wyiyiyi4 小时前
【Web后端】Django、flask及其场景——以构建系统原型为例
前端·数据库·后端·python·django·flask
gnip4 小时前
vite和webpack打包结构控制
前端·javascript
excel4 小时前
在二维 Canvas 中模拟三角形绕 X、Y 轴旋转
前端
阿华的代码王国5 小时前
【Android】RecyclerView复用CheckBox的异常状态
android·xml·java·前端·后端
一条上岸小咸鱼5 小时前
Kotlin 基本数据类型(三):Booleans、Characters
android·前端·kotlin
Jimmy5 小时前
AI 代理是什么,其有助于我们实现更智能编程
前端·后端·ai编程
ZXT5 小时前
promise & async await总结
前端
Jerry说前后端5 小时前
RecyclerView 性能优化:从原理到实践的深度优化方案
android·前端·性能优化
画个太阳作晴天5 小时前
A12预装app
linux·服务器·前端