javascript技巧

关注公众号 jb51net

关闭
首页 > 网络编程 > JavaScript > javascript技巧 > JavaScript图片懒加载

JavaScript实现图片懒加载的完整代码

作者:当时只道寻常

本文基于原生 JavaScript IntersectionObserver API 实现的图片懒加载方案知识库说明,文中的示例代码讲解详细,感兴趣的小伙伴可以了解一下

文档概述

本文基于原生 JavaScript IntersectionObserver API 实现的图片懒加载方案知识库说明,通过监听元素与视口的交叉状态,仅在图片进入视口时加载真实图片,减少初始页面加载资源消耗,提升页面性能与用户体验。

核心特性

  1. 原生 API 实现:基于 IntersectionObserver,无需引入第三方库,兼容性良好
  2. 性能优化:使用 DocumentFragment 批量操作 DOM,减少重绘重排
  3. 占位图策略:初始加载默认占位图,进入视口后替换为真实图片
  4. 自动停止观察:图片加载完成后自动取消观察,避免重复触发
  5. 视觉交互:包含卡片悬停缩放效果、自定义滚动条样式,提升用户体验

依赖说明

核心技术:原生 JavaScript(ES6+)、HTML5、CSS3

浏览器兼容性:支持 IntersectionObserver API 的现代浏览器(Chrome 51+、Firefox 55+、Safari 12.1+、Edge 79+)

外部资源:

完整代码实现

1. HTML 结构

<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8" />
  <meta http-equiv="X-UA-Compatible" content="IE=edge" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no" />
  <title>JavaScript Observer 实现懒加载</title>
  <link rel="stylesheet" href="./css/index.css" rel="external nofollow"  />
</head>
<body>
  <div class="card-list"></div>
  <script src="./js/index.js"></script>
</body>
</html>

2. CSS 样式

* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}
body {
  background-color: #f5f6f7;
}
.card-list {
  --ap-gap: 16px;
  --ap-min-width: 300px;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(var(--ap-min-width), 1fr));
  gap: var(--ap-gap);
  padding: 16px;
}
.card-list .item {
  cursor: pointer;
  height: 497px;
  border-radius: 10px;
  box-shadow: 0 0 6px #000;
  overflow: hidden;
}
.card-list .item:hover img {
  transform: scale(1.5);
}
.card-list .item img {
  display: block;
  width: 100%;
  height: 100%;
  transition: all 0.32s;
}
/* 自定义滚动条样式 */
::-webkit-scrollbar {
  width: 6px;
  height: 6px;
}
::-webkit-scrollbar-track {
  background-color: #f5f5f5;
}
::-webkit-scrollbar-track-piece {
  border-radius: 6px;
  background-color: #f5f5f5;
}
::-webkit-scrollbar-thumb {
  border-radius: 6px;
  background-color: #ccc;
}
::-webkit-scrollbar-thumb:hover {
  background-color: #a8a8a8;
}
::-webkit-scrollbar-thumb:active {
  background-color: #787878;
}
::-webkit-scrollbar-corner {
  background-color: #f5f5f5;
}
::-webkit-resizer {
  background-repeat: no-repeat;
  background-position: bottom right;
}

3. JavaScript 逻辑

// 配置项
const TOTAL_ITEMS = 99; // 总图片数量
const DEFAULT_IMG = 'https://pica.zhimg.com/v2-f052aa50ca65df4bad1c3b7e4084d00e_1440w.jpg'; // 默认占位图
const IMG_URL_TEMPLATE = (index) => `https://picsum.photos/400/600?r=${index}`; // 动态图片模板

const cardList = document.querySelector('.card-list');

/**
 * 生成图片卡片
 * 使用 DocumentFragment 批量操作 DOM,减少重绘重排
 */
function generateItems() {
  const fragment = document.createDocumentFragment();
  for (let i = 0; i < TOTAL_ITEMS; i++) {
    const div = document.createElement('div');
    div.classList.add('item');
    
    const img = document.createElement('img');
    img.src = DEFAULT_IMG; // 初始设置占位图
    img.dataset.src = IMG_URL_TEMPLATE(i); // 真实图片地址存储在 data-src
    img.alt = `Image ${i + 1}`;
    
    div.appendChild(img);
    fragment.appendChild(div);
  }
  cardList.appendChild(fragment); // 一次性插入所有元素
}

/**
 * 初始化 Intersection Observer
 * 监听图片与视口的交叉状态,实现懒加载
 */
function initLazyLoad() {
  const observer = new IntersectionObserver(
    (entries, observer) => {
      entries.forEach((entry) => {
        if (!entry.isIntersecting) return; // 跳过未进入视口的元素
        
        const img = entry.target;
        img.src = img.dataset.src; // 替换为真实图片
        observer.unobserve(img); // 加载完成后停止观察
      });
    },
    {
      threshold: 0.01, // 交叉阈值:元素 1% 进入视口时触发
    }
  );

  // 观察所有带有 data-src 属性的图片
  document.querySelectorAll('img[data-src]').forEach((img) => observer.observe(img));
}

// 执行主逻辑
generateItems();
initLazyLoad();

核心实现说明

图片卡片生成

Intersection Observer 初始化

API 说明

IntersectionObserver 配置

配置项类型默认值说明
thresholdnumber0元素与视口的交叉比例阈值,达到该比例时触发回调
rootElementnull观察的根元素,默认为视口
rootMarginstring'0px'根元素的外边距,用于提前或延迟触发

核心方法

方法名说明
observe(target)开始观察目标元素
unobserve(target)停止观察目标元素
disconnect()停止观察所有元素

使用示例

直接在浏览器中打开 HTML 文件即可体验:

  1. 页面初始加载 99 个带占位图的卡片
  2. 滚动页面,卡片进入视口时自动加载真实图片
  3. 鼠标悬停卡片,图片放大 1.5 倍
  4. 滚动条样式自定义,提升视觉体验

注意事项

  1. 浏览器兼容性IntersectionObserver 在 IE 及旧版本浏览器中不支持,如需兼容可引入 polyfill(如 intersection-observer
  2. 占位图优化:建议使用尺寸较小的占位图,减少初始加载资源
  3. 图片地址有效性:确保 data-src 存储的真实图片地址可访问
  4. 性能扩展:可结合 loading="lazy" 属性(原生懒加载)作为降级方案
  5. 错误处理:可添加图片加载失败的回调,替换为错误占位图
  6. 阈值调整:可根据实际需求调整 threshold 值,平衡加载时机与性能

到此这篇关于JavaScript实现图片懒加载的完整代码的文章就介绍到这了,更多相关JavaScript图片懒加载内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文