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


Posted in Javascript onOctober 20, 2016

前言

网络上各大论坛,尤其是一些图片类型的网站上,在图片加载时均采用了一种名为懒加载的方式,具体表现为,当页面被请求时,只加载可视区域的图片,其它部分的图片则不加载,只有这些图片出现在可视区域时才会动态加载这些图片,从而节约了网络带宽和提高了初次加载的速度,具体实现的技术并不复杂,下面分别对其说明。

Web 图片的懒加载就是通过读取img元素,然后获得img元素的data-src(也可以约定为其他属性名)属性的值,并赋予img的src,从而实现动态加载图片的机制。

这里需要注意的是: img在初始化的时候不要设置src属性,因为即使设置 src='' 浏览器也会尝试加载图片。

一个简单的图片懒加载共涉及两个方面

1. HTML 约定

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

具体示例为:

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

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的值赋予该图片。

太简单了?

事实就是如此!!!

如此简单,不妨扩展一下

添加一些自定义参数,谁都喜欢自定义,不是吗?

支持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]);
 }
 };
})();

总结

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

Javascript 相关文章推荐
javascript知识点收藏
Feb 22 Javascript
基于jquery的划词搜索实现(备忘)
Sep 14 Javascript
Json2Template.js 基于jquery的插件 绑定JavaScript对象到Html模板中
Oct 29 Javascript
页面元素绑定jquery toggle后元素隐藏的解决方法
Mar 27 Javascript
基于jQuery.Hz2Py.js插件实现的汉字转拼音特效
May 07 Javascript
javascript最基本的函数汇总
Jun 25 Javascript
JavaScript易错知识点整理
Dec 05 Javascript
jQuery实现模糊搜索功能的方法分析
Jun 29 jQuery
js中怎么判断两个字符串相等的实例
Jan 17 Javascript
微信小程序实现基于三元运算验证手机号/姓名功能示例
Jan 19 Javascript
ES6基础之默认参数值
Feb 21 Javascript
微信小程序跨页面传递data数据方法解析
Dec 13 Javascript
Vue.js Ajax动态参数与列表显示实现方法
Oct 20 #Javascript
探究Vue.js 2.0新增的虚拟DOM
Oct 20 #Javascript
Javascript 创建类并动态添加属性及方法的简单实现
Oct 20 #Javascript
javascript匀速动画和缓冲动画详解
Oct 20 #Javascript
js设置和获取自定义属性的方法
Oct 20 #Javascript
js阻止冒泡和默认事件(默认行为)详解
Oct 20 #Javascript
浅谈JS中String()与 .toString()的区别
Oct 20 #Javascript
You might like
yii框架源码分析之创建controller代码
2011/06/28 PHP
自己写了一个php检测文件编码的函数
2014/04/21 PHP
windows7下安装php的php-ssh2扩展教程
2014/07/04 PHP
初识php MVC
2014/09/10 PHP
PHP开发中AJAX技术的简单应用
2015/12/11 PHP
thinkphp5框架前后端分离项目实现分页功能的方法分析
2019/10/08 PHP
JavaScript替换当前页面的方法
2015/04/03 Javascript
AngularJS中处理多个promise的方式
2016/02/02 Javascript
微信小程序使用第三方库Immutable.js实例详解
2016/09/27 Javascript
vue.js绑定class和style样式(6)
2016/12/09 Javascript
select下拉框插件jquery.editable-select详解
2017/01/22 Javascript
javascript中apply/call和bind的使用
2017/02/15 Javascript
angular bootstrap timepicker TypeError提示怎么办
2017/06/13 Javascript
ionic环境配置及问题详解
2017/06/27 Javascript
Angular4实现图片上传预览路径不安全的问题解决
2017/12/25 Javascript
vue组件从开发到发布的实现步骤
2018/11/11 Javascript
[09:37]DOTA2卡尔工作室 英雄介绍圣堂刺客篇
2013/06/13 DOTA
python列表操作使用示例分享
2014/02/21 Python
PyTorch 1.0 正式版已经发布了
2018/12/13 Python
Python子类继承父类构造函数详解
2019/02/19 Python
python绘制地震散点图
2019/06/18 Python
Python绘图Matplotlib之坐标轴及刻度总结
2019/06/28 Python
Python-copy()与deepcopy()区别详解
2019/07/12 Python
python开发一款翻译工具
2020/10/10 Python
Opencv python 图片生成视频的方法示例
2020/11/18 Python
销售员自我评价怎么写
2013/09/19 职场文书
《金钱的魔力》教学反思
2014/02/24 职场文书
亲子活动总结
2014/04/26 职场文书
群众路线党员自我评议范文2014
2014/09/24 职场文书
保险内勤岗位职责
2015/04/13 职场文书
债务纠纷起诉书
2015/05/20 职场文书
刑事申诉状范文
2015/05/20 职场文书
行政二审代理词
2015/05/25 职场文书
学校安全管理制度
2015/08/06 职场文书
自己搭建resnet18网络并加载torchvision自带权重的操作
2021/05/13 Python
Mysql 一主多从的部署
2022/05/20 MySQL