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去除空格的几种方法
Oct 03 Javascript
nullJavascript中创建对象的五种方法实例
May 07 Javascript
简单的Jquery全选功能
Nov 07 Javascript
js获取当前路径的简单示例代码
Jan 08 Javascript
基于jquery css3实现点击动画弹出表单源码特效
Aug 31 Javascript
关于angularJs指令的Scope(作用域)介绍
Oct 25 Javascript
JavaScript实现的超简单计算器功能示例
Dec 23 Javascript
vue2.0 根据状态值进行样式的改变展示方法
Mar 13 Javascript
JavaScript设计模式之观察者模式(发布订阅模式)原理与实现方法示例
Jul 27 Javascript
JavaScript常用工具方法封装
Feb 12 Javascript
小程序实现搜索界面 小程序实现推荐搜索列表效果
May 18 Javascript
JavaScript冒泡算法原理与实现方法深入理解
Jun 04 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
全新的PDO数据库操作类php版(仅适用Mysql)
2012/07/22 PHP
php中Ctype函数用法详解
2014/12/09 PHP
AJAX PHP无刷新form表单提交的简单实现(推荐)
2016/09/09 PHP
php 使用html5实现多文件上传实例
2016/10/24 PHP
javascript下IE与FF兼容函数收集
2008/09/17 Javascript
JavaScript 检测浏览器和操作系统的脚本
2008/12/26 Javascript
网页前台通过js非法字符过滤代码(骂人的话等等)
2010/05/26 Javascript
js+CSS实现弹出居中背景半透明div层的方法
2015/02/26 Javascript
jQuery实现的分子运动小球碰撞效果
2016/01/27 Javascript
Bootstrap学习笔记之环境配置(1)
2016/12/07 Javascript
关于使用axios的一些心得技巧分享
2017/07/02 Javascript
微信小程序HTTP请求从0到1封装
2019/09/09 Javascript
vue用BMap百度地图实现即时搜索功能
2019/09/26 Javascript
JavaScript代码异常监控实现过程详解
2020/02/17 Javascript
浅谈vue在html中出现{{}}的原因及解决方式
2020/11/16 Javascript
vue实现按钮切换图片
2021/01/20 Vue.js
JS实现点击掉落特效
2021/01/29 Javascript
[57:55]EG vs Fnatic 2018国际邀请赛小组赛BO2 第一场 8.19
2018/08/21 DOTA
python网络编程调用recv函数完整接收数据的三种方法
2017/03/31 Python
Android基于TCP和URL协议的网络编程示例【附demo源码下载】
2018/01/23 Python
谈谈Python中的while循环语句
2019/03/10 Python
详解Python中的内建函数,可迭代对象,迭代器
2019/04/29 Python
python 读写excel文件操作示例【附源码下载】
2019/06/19 Python
anaconda如何查看并管理python环境
2019/07/05 Python
Python3 中作为一等对象的函数解析
2019/12/11 Python
求两个数的乘积和商数,该作用由宏定义来实现
2013/03/13 面试题
九年级体育教学反思
2014/01/23 职场文书
销售类求职信
2014/06/13 职场文书
志愿者活动总结报告
2014/06/27 职场文书
2015年技术员工作总结
2015/04/10 职场文书
悬崖上的金鱼姬观后感
2015/06/15 职场文书
关于感恩的作文
2019/08/26 职场文书
MYSQL 表的全面总结
2021/11/11 MySQL
Python中request的基本使用解决乱码问题
2022/04/12 Python
MySQL中的全表扫描和索引树扫描
2022/05/15 MySQL
Java Redisson多策略注解限流
2022/09/23 Java/Android