学习JavaScript图片预加载模块


Posted in Javascript onNovember 07, 2016

前言

在一个应用中,通常会有很多图片,众所周知,加载图片需要时间,在图片没有加载出来之前,页面会是空白,为了提升用户体验,应用的开发人员使出浑身解数,其中最为常见的就是在图片没有加载完成之前,有一个加载动画。这里用到的技术主要是图片预加载。图片预加载的原理并不难,当给一个Image对象设置src属性后,图片就开始加载。给Image对象指定事件要位于设置src属性之前。

涉及到的内容

1.需要预加载的图片并不仅仅只是一张,通常将所有图片的信息保存在一个数组或者对象中,为了加载所有的图片,需要遍历出所有的图片。

2.当所有图片加载完后,又要接着执行其他的任务,这需要一个回调函数。

3.记录已经完成加载的图片数量,并实时的反应到页面上。

编码开始

注:html和css省略,主要讲解js文件

1.为了代码复用,我将图片预加载相关的代码封装在imageloader.js模块中,并暴露出一个接口。

2.入口文件是index.js,入口文件的代码如下:

var loadImage = require('./imageloader.js');
loadImage(['./img/rabbit-big.png','./img/face_slogan.png','./img/footer.png'],finish);
//finish是一个所以图片完成加载之后执行的回调函数
function finish(){
 document.body.innerHTML = '完成加载'
 }

3.imageloader.js模块代码入下:

'use strict';

/**
 * 预加载图片的函数
 * @param elem 显示加载进度的元素
 * @param images 加载图片的数组或者对象
 * @param callback 全部图片加载完毕后调用的回调函数
 * @param timeout 加载超时的时长
 */
function loadImage(elem,images,callback,timeout){
 //遍历出图片的计数器
 var count = 0;
 //默认全部图片都能成功加载
 var success = true;
 //超时timer的id
 var timerId = 0;
 //默认不会加载超时
 var isTimeout = false;
 //已经加载完成的长度
 var loaded = 0;

 //对图片数组(或对象)进行遍历
 for(var key in images){
 //过滤掉prototype上的属性
 if(!images.hasOwnProperty(key)){
 continue;
 }
 //获得每个图片元素
 //期望每个图片元素是一个object:{src:XXX}
 var item = images[key];
 if(typeof item === "string"){
 item = images[key] = {
 src:item
 }
 }
 //如果格式不满足期望,则进行下一次遍历
 if(!item || !item.src){
 continue;
 }
 //计算+1
 ++ count;
 //设置图片元素的id
 item.id = '__img__' + key + getId();
 //设置图片元素的image,它是一个image对象
 item.image = window[item.id] = new Image();

 doLoad(item);
 }
 //如果计数为0,则直接调用callback
 if(!count){
 callback(success);
 }else if(timeout){//如果设置了最长加载时间
 timerId = setTimeout(onTimeout,timeout)
 }
 /**
 * 真正进行图片预加载的函数
 * @param item 图片元素的对象
 */
 function doLoad(item){
 item.state = 'loading';

 var img = item.image;
 //图片加载成功的一个回调函数
 img.onload = function(){
 //只要有一张出现加载失败,success就会为false
 success = success & true;
 item.state = 'load';
 loaded ++;
 done();

 };
 //图片加载失败的回调函数
 img.onerror = function(){
 success = false;
 item.state = 'error';
 loaded ++;
 done();
 };
 //加载图片
 img.src = item.src;
 /**
 * 每张图片加载完成的回调函数,不论成功还是失败
 */
 function done(){
 //清除绑定的事件
 img.onload = null;
 img.onerror = null;
 try{
 delete window[item.id]
 }catch (e){

 }
 elem.innerHTML = '已加载' + (loaded / count * 100) + '%';
 //当所有图片加载完成并且没有超时的情况,清除定时器,且执行回调函数
 if(count === loaded && !isTimeout){
 clearTimeout(timerId);
 callback(success);
 }
 }
 }

 /**
 * 超时函数
 */
 function onTimeout(){
 isTimeout = true;
 success = false;
 callback(success);
 }

}

var __id = 0;
function getId(){
 return ++ __id;
}
module.exports = loadImage;

4.我使用的是webpack进行打包,如果你对打包还不熟悉,可以点击这儿学习。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
JavaScript 输入框内容格式验证代码
Feb 11 Javascript
jQuery插件 selectToSelect使用方法
Oct 02 Javascript
JQuery为页面Dom元素绑定事件及解除绑定方法
Apr 23 Javascript
10个很棒的jQuery代码片段
Sep 24 Javascript
深入理解javascript的getTime()方法
Feb 16 Javascript
Vue.js基础学习之class与样式绑定
Mar 20 Javascript
深入浅析Vue中的Prop
Jun 10 Javascript
JS使用tween.js动画库实现轮播图并且有切换功能
Jul 17 Javascript
微信小程序和百度的语音识别接口详解
May 06 Javascript
使用layui定义一个模块并使用的例子
Sep 14 Javascript
vue 组件间的通信之子组件向父组件传值的方式
Jul 29 Javascript
element el-table表格的二次封装实现(附表格高度自适应)
Jan 19 Javascript
pc加载更多功能和移动端下拉刷新加载数据
Nov 07 #Javascript
jquery html5 视频播放控制代码
Nov 06 #Javascript
js无提示关闭浏览器窗口的两种方法分析
Nov 06 #Javascript
详解Angular.js的$q.defer()服务异步处理
Nov 06 #Javascript
Bootstrap 3.x打印预览背景色与文字显示异常的解决
Nov 06 #Javascript
d3.js实现简单的网络拓扑图实例代码
Nov 06 #Javascript
HTML5 JS压缩图片并获取图片BASE64编码上传
Nov 16 #Javascript
You might like
用cookies来跟踪识别用户
2006/10/09 PHP
一个PHP模板,主要想体现一下思路
2006/12/25 PHP
PHP 加密与解密的斗争
2009/04/17 PHP
PHP yield关键字功能与用法分析
2019/01/03 PHP
laravel 实现上传图片到本地和前台访问示例
2019/10/21 PHP
PHP的new static和new self的区别与使用
2019/11/27 PHP
jQuery 下拉列表 二级联动插件分享
2012/03/29 Javascript
鼠标经过tr时,改变tr当前背景颜色
2014/01/13 Javascript
jQuery的live()方法对hover事件的处理示例
2014/02/27 Javascript
javascript 兼容各个浏览器的事件
2015/02/04 Javascript
jquery实现点击变换导航样式的方法
2015/08/31 Javascript
Position属性之relative用法
2015/12/14 Javascript
JavaScript如何实现在文本框(密码框)输入提示语
2015/12/25 Javascript
Node.js如何实现注册邮箱激活功能 (常见)
2017/07/23 Javascript
vue slots 组件的组合/分发实例
2018/09/06 Javascript
react-router 路由切换动画的实现示例
2018/12/03 Javascript
vue车牌号校验和银行校验实战
2019/01/23 Javascript
Tornado服务器中绑定域名、虚拟主机的方法
2014/08/22 Python
分享Python文本生成二维码实例
2016/01/06 Python
使用Python对Excel进行读写操作
2017/03/30 Python
python+pandas+时间、日期以及时间序列处理方法
2018/07/10 Python
python 解决selenium 中的 .clear()方法失效问题
2020/09/01 Python
python时间time模块处理大全
2020/10/25 Python
利用python+request通过接口实现人员通行记录上传功能
2021/01/13 Python
英国领先的大码时装品牌之一:Elvi
2018/08/26 全球购物
Molton Brown美国官网:奢华美容、香水、沐浴和身体护理
2020/09/02 全球购物
金智子午JAVA面试题
2015/09/04 面试题
教师求职推荐信范文
2013/11/20 职场文书
简历的自我评价
2014/02/03 职场文书
环境保护建议书
2014/08/26 职场文书
社区四风存在问题及整改措施
2014/10/26 职场文书
幼儿园三八妇女节活动总结
2015/02/06 职场文书
青岛海底世界导游词
2015/02/11 职场文书
2015年秘书个人工作总结
2015/04/25 职场文书
小学校本教研总结
2015/08/13 职场文书
css3 利用transform-origin 实现圆点分布在大圆上布局及旋转特效
2021/04/29 HTML / CSS