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实现CheckBox的全选与取消全选的代码
Jul 20 Javascript
window.opener用法和用途实例介绍
Aug 19 Javascript
jquery判断元素的子元素是否存在的示例代码
Feb 04 Javascript
关于JavaScript对象的动态选择及遍历对象
Mar 10 Javascript
js获取字符串字节数方法小结
Jun 09 Javascript
js验证身份证号有效性并提示对应信息
Oct 19 Javascript
jQuery监听文件上传实现进度条效果的方法
Oct 16 Javascript
JavaScript中关于for循环删除数组元素内容时出现的问题
Nov 21 Javascript
JS作用域深度解析
Dec 29 Javascript
EasyUI为Numberbox添加blur事件的方法
Mar 05 Javascript
vue实现某元素吸顶或固定位置显示(监听滚动事件)
Dec 13 Javascript
详解JavaScript匿名函数和闭包
Jul 10 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
洪恩在线成语词典小偷程序php版
2012/04/20 PHP
PHP不使用内置函数实现字符串转整型的方法示例
2017/07/03 PHP
利用PHP计算有多少小于当前数字的数字方法示例
2020/08/26 PHP
javascript 限制输入脚本大全
2009/11/03 Javascript
文本框的字数限制功能jquery插件
2009/11/24 Javascript
js实现浏览器的各种菜单命令比如打印、查看源文件等等
2013/10/24 Javascript
js读取cookie方法总结
2014/10/31 Javascript
基于JQuery制作可编辑的表格特效
2014/12/23 Javascript
JavaScript语言对Unicode字符集的支持详解
2014/12/30 Javascript
jQuery+formdata实现上传进度特效遇到的问题
2016/02/24 Javascript
jQuery过滤选择器经典应用
2016/08/18 Javascript
jQuery simpleModal插件的使用介绍
2016/08/30 Javascript
javascript滚轮控制模拟滚动条
2016/10/19 Javascript
日期时间范围选择插件:daterangepicker使用总结(必看篇)
2017/09/14 Javascript
微信小程序 循环及嵌套循环的使用总结
2017/09/26 Javascript
在NodeJs中使用node-schedule增加定时器任务的方法
2020/06/08 NodeJs
解决vue项目打包上服务器显示404错误,本地没出错的问题
2020/11/03 Javascript
[36:43]NB vs Optic 2018国际邀请赛小组赛BO1 B组加赛 8.19
2018/08/21 DOTA
Python面向对象特殊成员
2017/04/24 Python
浅析Python装饰器以及装饰器模式
2018/05/28 Python
python 通过SSHTunnelForwarder隧道连接redis的方法
2019/02/19 Python
Python Matplotlib实现三维数据的散点图绘制
2019/03/19 Python
python并发编程多进程之守护进程原理解析
2019/08/20 Python
python科学计算之narray对象用法
2019/11/25 Python
基于numpy中的expand_dims函数用法
2019/12/18 Python
Python实现转换图片背景颜色代码
2020/04/30 Python
利用python进行文件操作
2020/12/04 Python
Hunter Boots美国官方网站:赫特威灵顿雨靴
2018/06/16 全球购物
大学生毕业求职找工作的自我评价
2013/09/29 职场文书
会计专业大学生求职信范文
2014/01/28 职场文书
大学考试作弊检讨书
2014/01/30 职场文书
班主任班级管理心得体会
2016/01/07 职场文书
机关单位2016年创先争优活动总结
2016/04/05 职场文书
Python制作一个随机抽奖小工具的实现
2021/07/07 Python
使用Oracle命令进行数据库备份与还原
2021/12/06 Oracle
Python作用域和名称空间的详细介绍
2022/04/13 Python