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 相关文章推荐
用 JSON 处理缓存
Apr 27 Javascript
JS 日期验证正则附asp日期格式化函数
Sep 11 Javascript
解决IE下select标签innerHTML插入option的BUG(兼容IE,FF,Opera,Chrome,Safari)
May 13 Javascript
理解Javascript_07_理解instanceof实现原理
Oct 15 Javascript
流量统计器如何鉴别C#:WebBrowser中伪造referer
Jan 07 Javascript
详解Html a标签中href和onclick用法、区别、优先级别
Jan 16 Javascript
详解Nuxt.js Vue服务端渲染摸索
Feb 08 Javascript
VUE的history模式下除了index外其他路由404报错解决办法
Aug 21 Javascript
layui自定义验证,用ajax查询后台是否有重复数据,form.verify的例子
Sep 06 Javascript
Vue-drag-resize 拖拽缩放插件的使用(简单示例)
Dec 04 Javascript
JavaScript大数相加相乘的实现方法实例
Oct 18 Javascript
vue动态设置路由权限的主要思路
Jan 13 Vue.js
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 socke 向指定页面提交数据
2008/07/23 PHP
php数据库连接时容易出错的特殊符号问题
2010/09/01 PHP
PHP实现通过二维数组键值获取一维键名操作示例
2019/10/11 PHP
escape、encodeURI、encodeURIComponent等方法的区别比较
2006/12/27 Javascript
javascript Discuz代码中的msn聊天小功能
2008/05/25 Javascript
JQUERY设置IFRAME的SRC值的代码
2010/11/30 Javascript
菜鸟javascript基础资料整理2
2010/12/06 Javascript
JS弹出对话框返回值代码(asp.net后台)
2010/12/28 Javascript
jquery随机展示头像代码
2011/12/21 Javascript
javascript 获取HTML DOM父、子、临近节点
2014/06/16 Javascript
深入理解JavaScript系列(44):设计模式之桥接模式详解
2015/03/04 Javascript
微信小程序-小说阅读小程序实例(demo)
2017/01/12 Javascript
Javascript Event(事件)的传播与冒泡
2017/01/23 Javascript
vue 打包后的文件部署到express服务器上的方法
2017/08/09 Javascript
前端图片懒加载(lazyload)的实现方法(提高用户体验)
2017/08/21 Javascript
小程序实现短信登录倒计时
2019/07/12 Javascript
Nodejs中使用puppeteer控制浏览器中视频播放功能
2019/08/26 NodeJs
python嵌套字典比较值与取值的实现示例
2017/11/03 Python
使用apidoc管理RESTful风格Flask项目接口文档方法
2018/02/07 Python
Python判断一个文件夹内哪些文件是图片的实例
2018/12/07 Python
python爬虫开发之urllib模块详细使用方法与实例全解
2020/03/09 Python
Python selenium页面加载慢超时的解决方案
2020/03/18 Python
css3 响应式媒体查询的示例代码
2019/09/25 HTML / CSS
瑞贝卡·泰勒官方网站:Rebecca Taylor
2016/09/24 全球购物
HomeAway英国:全球领先的度假租赁在线市场
2020/02/03 全球购物
数控专业推荐信范文
2013/12/02 职场文书
校园之声广播稿
2014/01/31 职场文书
国际贸易专业个人求职信格式
2014/02/02 职场文书
测绘专业大学生职业生涯规划书
2014/02/10 职场文书
《小壁虎借尾巴》教学反思
2014/02/16 职场文书
企业员工培训感言
2014/02/26 职场文书
廉政教育的心得体会
2014/09/01 职场文书
2014党员学习习主席讲话思想汇报
2014/09/15 职场文书
离婚上诉状范文
2015/05/23 职场文书
实习单位意见
2015/06/04 职场文书
导游词之泰山玉皇顶
2019/12/23 职场文书