JavaScript实现图片懒加载插件的方法

作者:性能诊所时间:2026-10-31 03:22:28浏览:638

本文详细介绍了一种基于JavaScript的图片懒加载实现方案。通过监听页面滚动事件,判断图片是否进入可视区域,动态将data-src赋值给src属性,从而减少初始加载时间并节约带宽。文章提供了完整的代码示例及针对iScroll等滚动库的扩展方法,帮助开发者提升网页加载性能。

前言

图片懒加载原理与HTML约定

在各类网络论坛及以图片展示为主的网站上,普遍采用一种称为懒加载的技术。其核心机制是:当页面请求加载时,仅渲染可视区域内的图片,其余图片暂不加载。只有当用户滚动页面使图片进入可视范围时,才动态触发加载。这种方式有效节省了网络带宽,并显著提升了页面的首次加载速度。

Web图片懒加载的实现原理是:遍历页面上的img元素,读取其data-src属性(也可自定义其他属性名)中存储的图片地址,并将其赋值给img的src属性,以此完成图片的动态加载。

需要注意的是,在初始化阶段不应直接设置src属性。因为即使设置了src='' ,浏览器仍会尝试立即加载图片,从而失去懒加载的意义。

实现一个基础的图片懒加载功能主要涉及两个关键环节。

1. HTML 约定

我们首先需要给准备实施懒加载的img元素添加指定的class 这里为m-lazyload ,同时将img src赋值给 data-src属性。

具体示例为:


<img class="m-lazyload" data-src="imgUrl">

JavaScript实现步骤

2. JavaScript 实现

动态加载逻辑可分为以下几个步骤,每个步骤对应一个独立的函数。

1. 添加页面滚动监听事件


window.addEventListener('scroll', _delay, false);

function _delay() {
 clearTimeout(delay);
 delay = setTimeout(function () {
 _loadImage();
 }, time);
}

2. 当触发监听事件时,执行_loadImage函数,该函数负责执行实际的图片加载操作。


function _loadImage() {
 for (var i = imgList.length; i--;) {
 var el = imgList[i];
 if (_isShow(el)) {
  el.src = el.getAttribute('data-src');
  el.className = el.className.replace(new RegExp("(\\s|^)" + _selector.substring(1, _selector.length) + "(\\s|$)"), " ");
  imgList.splice(i, 1);
 }
 }
}

虽然调用了_loadImage函数,但我们需要明确哪些图片应当被加载。判断的依据是什么?

判断依据是:该图片当前是否位于窗口的可视区域内。为此,我们封装一个_isShow函数来实现这一判断逻辑。


function _isShow(el) {
 var coords = el.getBoundingClientRect();
 return ( (coords.top >= 0 && coords.left >= 0 && coords.top) <= (window.innerHeight || document.documentElement.clientHeight) + parseInt(offset));
}

至此,一个完整的图片加载闭环已构建完成。

当网页滚动事件被触发 -> 执行加载图片操作 -> 判断图片是否在可视区域内 -> 若在,则动态将data-src的值赋予该图片的src属性。

这看起来太简单了?

事实就是如此简单。

功能扩展与优化

既然基础功能已实现,不妨进行扩展。

添加一些自定义参数,开发者通常喜欢这种灵活性。

支持iScroll,iScroll是一个高性能、资源占用少、无依赖且多平台的JavaScript滚动插件。

这里我们做了一些优化处理。

图片加载完成后移除相关选择器,避免重复判断。

缓存img元素集合,减少dom元素查询带来的性能损耗。

扩展prototype并添加getNode方法,以支持分页数据的懒加载(得益于之前缓存的dom元素)。

OK!说了这么多,show me the code 吧!


(function () {
 var imgList = [], // 页面所有img元素集合
 delay, // setTimeout 对象
 offset, //偏移量,用于指定图片距离可视区域多少距离,进行加载
 time, // 延迟载入时间
 _selector; // 选择器 默认为 .m-lazyload

 function _isShow(el) {
 var coords = el.getBoundingClientRect();
 return ( (coords.top >= 0 && coords.left >= 0 && coords.top) <= (window.innerHeight || document.documentElement.clientHeight) + parseInt(offset));
 }

 function _loadImage() {
 for (var i = imgList.length; i--;) {
  var el = imgList[i];
  if (_isShow(el)) {
  el.src = el.getAttribute('data-src');
  el.className = el.className.replace(new RegExp("(\\s|^)" + _selector.substring(1, _selector.length) + "(\\s|$)"), " ");
  imgList.splice(i, 1);
  }
 }
 }

 function _delay() {
 clearTimeout(delay);
 delay = setTimeout(function () {
  _loadImage();
 }, time);
 }

 function ImageLazyload(selector, options) {
 var defaults = options || {};
 offset = defaults.offset || 0;
 time = defaults.time || 250;
 _selector = selector || '.m-lazyload';
 this.getNode();
 _delay();//避免首次加载未触发touch事件,主动触发一次加载函数
 if (defaults.iScroll) {
  defaults.iScroll.on('scroll', _delay);
  defaults.iScroll.on('scrollEnd', _delay);
 } else {
  window.addEventListener('scroll', _delay, false);
 }
 }
 ImageLazyload.prototype.getNode = function () {
 imgList = [];
 var nodes = document.querySelectorAll(_selector);
 for (var i = 0, l = nodes.length; i < l; i++) {
  imgList.push(nodes[i]);
 }
 };
})();

总结

以上就是这篇文章的全部内容,希望本文的内容对大家学习或者使用图片懒加载的时候能有所帮助,如果有疑问大家可以留言交流。

作者最新文章