学习JavaScript图片预加载模块

所属分类: 网络编程 / JavaScript 阅读数: 1675
收藏 0 赞 0 分享

前言

在一个应用中,通常会有很多图片,众所周知,加载图片需要时间,在图片没有加载出来之前,页面会是空白,为了提升用户体验,应用的开发人员使出浑身解数,其中最为常见的就是在图片没有加载完成之前,有一个加载动画。这里用到的技术主要是图片预加载。图片预加载的原理并不难,当给一个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进行打包,如果你对打包还不熟悉,可以点击这儿学习。

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

更多精彩内容其他人还在看

Canvas实现放射线动画效果

本文主要分享了Canvas实现放射线动画的示例代码。具有很好的参考价值,下面跟着小编一起来看下吧
收藏 0 赞 0 分享

微信小程序 image组件binderror使用例子与js中的onerror区别

这篇文章主要介绍了微信小程序 image组件binderror使用例子与js中的onerror区别的相关资料,需要的朋友可以参考下
收藏 0 赞 0 分享

原生js轮播(仿慕课网)

本文主要分享了原生js实现仿慕课网的轮播效果。具有很好的参考价值,下面跟着小编一起来看下吧
收藏 0 赞 0 分享

Bootstrap table简单使用总结

这篇文章主要为大家总结了Bootstrap table的简单使用方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
收藏 0 赞 0 分享

微信小程序之MaterialDesign--input组件详解

本篇文章主要介绍了微信小程序之MaterialDesign--input组件详解,具有一定的参考价值,感兴趣的小伙伴们可以参考一下。
收藏 0 赞 0 分享

浅析javaScript中的浅拷贝和深拷贝

本篇文章主要介绍了浅析javaScript中的浅拷贝和深拷贝,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
收藏 0 赞 0 分享

js时间戳和c#时间戳互转方法(推荐)

下面小编就为大家带来一篇js时间戳和c#时间戳互转方法(推荐)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
收藏 0 赞 0 分享

Bootstrap模态框使用详解

这篇文章主要为大家详细介绍了Bootstrap模态框的使用方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
收藏 0 赞 0 分享

Jil,高效的json序列化和反序列化库

下面小编就为大家带来一篇Jil,高效的json序列化和反序列化库。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
收藏 0 赞 0 分享

BootStrap实现带关闭按钮功能

这篇文章主要介绍了BootStrap实现带关闭按钮功能,非常不错,具有参考借鉴价值,需要的朋友可以参考下
收藏 0 赞 0 分享
查看更多