图片懒加载的实现

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

  • 加载时机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 事件)。

相关推荐
八了个戒14 分钟前
「数据可视化 D3系列」入门第三章:深入理解 Update-Enter-Exit 模式
开发语言·前端·javascript·数据可视化
noravinsc42 分钟前
html页面打开后中文乱码
前端·html
小满zs1 小时前
React-router v7 第四章(路由传参)
前端·react.js
小陈同学呦1 小时前
聊聊双列瀑布流
前端·javascript·面试
键指江湖2 小时前
React 在组件间共享状态
前端·javascript·react.js
诸葛亮的芭蕉扇2 小时前
D3路网图技术文档
前端·javascript·vue.js·microsoft
小离a_a2 小时前
小程序css实现容器内 数据滚动 无缝衔接 点击暂停
前端·css·小程序
徐小夕3 小时前
花了2个月时间研究了市面上的4款开源表格组件,崩溃了,决定自己写一款
前端·javascript·react.js
by————组态3 小时前
低代码 Web 组态
前端·人工智能·物联网·低代码·数学建模·组态
拉不动的猪3 小时前
UniApp金融理财产品项目简单介绍
前端·javascript·面试