当前位置: 首页 > article >正文

基础前端面试题:HTML网站开发中,如何实现图片的懒加载

懒加载,顾名思义,在当前网页,滑动页面到能看到图片的时候再加载图片

故问题拆分成两个:

  1. 如何判断图片出现在了当前视口 (即如何判断我们能够看到图片)
  2. 如何控制图片的加载

方案 1:使用 IntersectionObserver(推荐)

IntersectionObserver 是现代浏览器提供的 API,可高效监听元素是否进入视口。

实现步骤
  1. img 添加 data-src 存储真实图片 URL,初始 src 设为空或占位图。
  2. 使用 IntersectionObserver 监听图片是否进入视口。
  3. 进入视口时,将 data-src 赋值给 src,触发图片加载。
代码示例
<img class="lazy" data-src="real-image.jpg" src="placeholder.jpg" alt="Lazy Image">
document.addEventListener("DOMContentLoaded", function () {
    let lazyImages = document.querySelectorAll("img.lazy");

    let observer = new IntersectionObserver((entries, observer) => {
        entries.forEach(entry => {
            if (entry.isIntersecting) {
                let img = entry.target;
                img.src = img.dataset.src;
                img.classList.remove("lazy"); // 移除类,避免重复加载
                observer.unobserve(img); // 取消观察,减少性能消耗
            }
        });
    }, {
        root: null, // 视口
        threshold: 0.1 // 触发懒加载的阈值
    });

    lazyImages.forEach(img => observer.observe(img));
});

优点

  • 高效:浏览器 API 提供回调,仅在图片进入视口时触发。
  • 可控:可自定义触发阈值 threshold(例如 0.1 表示 10% 进入视口时加载)。

方案 2:使用 getBoundingClientRect() + scroll 事件(兼容旧浏览器)

如果需要支持不兼容 IntersectionObserver 的旧版浏览器,可以使用 getBoundingClientRect() 结合 scroll 事件手动监听。

实现步骤
  1. 监听 scroll 事件,遍历所有 lazy 图片。
  2. 使用 getBoundingClientRect() 判断图片是否进入视口。
  3. 进入视口后加载图片并移除监听。
代码示例
function lazyLoad() {
    let lazyImages = document.querySelectorAll("img.lazy");
    let windowHeight = window.innerHeight;

    lazyImages.forEach(img => {
        let rect = img.getBoundingClientRect();
        if (rect.top < windowHeight && rect.bottom > 0) { // 判断是否在视口内
            img.src = img.dataset.src;
            img.classList.remove("lazy");
        }
    });

    if (document.querySelectorAll("img.lazy").length === 0) {
        window.removeEventListener("scroll", lazyLoad); // 所有图片加载完后移除事件监听
    }
}

document.addEventListener("DOMContentLoaded", () => {
    window.addEventListener("scroll", lazyLoad);
    lazyLoad(); // 初次执行,确保首屏图片加载
});

缺点

  • 性能问题scroll 事件会频繁触发,需要使用 防抖debounce)优化。
  • 兼容性好:适用于旧版浏览器。

方案 3:使用 loading="lazy"(最简单,浏览器原生支持)

HTML5 提供 loading="lazy" 属性,浏览器会自动判断图片是否需要懒加载。

<img src="real-image.jpg" loading="lazy" alt="Lazy Image">

优点

  • 最简单,无需 JS,浏览器自动处理懒加载。
  • 兼容性一般,现代浏览器(Chrome 76+,Firefox 75+,Edge 79+)支持。

缺点

  • 无法自定义触发时机,受浏览器策略控制。
  • 不支持旧版浏览器,如 Safari 15 之前。

最佳方案推荐

  1. 现代浏览器:使用 IntersectionObserver(推荐)
  2. 兼容性要求高scroll + getBoundingClientRect()
  3. 简单项目:直接用 loading="lazy"(最方便)

http://www.kler.cn/a/554673.html

相关文章:

  • rust笔记7-生命周期显式标注
  • 3分钟了解内外网文件传输:常见方法、注意事项有哪些?
  • 13-R数据重塑
  • 后端Java Stream数据流的使用=>代替for循环
  • Compose 组件渲染流程
  • 如何在Ubuntu 22.04上安装NVIDIA驱动:自动安装与手动安装的全面指南
  • 非常简洁的一个 Excel 导出封装,生成多个 Excel 文件并打包成 zip 通过浏览器下载
  • 责任链模式原理详解和源码实例以及Spring AOP拦截器链的执行源码如何使用责任链模式?
  • UEFI Spec 学习笔记---6 - Block Translation Table (BTT) Layout
  • 算法从0到100之【专题一】- 双指针第一练(数组划分、数组分块)
  • AI 是如何赋能企业,推动新的“商业革命”的?
  • 国产编辑器EverEdit -告别东找西找!一键打开当前文件所在目录!
  • RocketMQ保证消息有序性
  • linux5-多任务--进程fork()
  • 力扣hot100 ——和为k的子数组 前后缀和(积)各种情况总结
  • 大模型高效注意力机制全解析:FlashAttention 与稀疏注意力实战
  • 【自动化脚本工具】Hammerspoon (Mac)
  • 基于STM32与IFX007T的电机驱动全解析(无人机/机器人实战)
  • 【队列】循环队列(Circular Queue)详解
  • 美的楼宇科技基于阿里云 EMR Serverless Spark 构建 LakeHouse 湖仓数据平台