js图片预加载详解
图片预加载技术在当前的应用非常的广泛,比如在鼠标悬浮图片实现翻转效果中,如果图片还没有加载完成,那么此效果的人性化程度就会大打折扣,甚至会给网站减分。如果将需要的图片事先下载到本地,那么就可以让效果流畅的进行。这就是所谓的图片预加载,下面详细介绍一下它的实现过程。下面先看一个基本的图片预加载代码:
function preloadimages(arr){ var newimages=[] var arr=(typeof arr!="object")? [arr] : arr;//确保参数总是数组 for (var index=0; index<arr.length; index++){ newimages[index]=new Image() newimages[index].src=arr[index] } }
上面的代码实现了最基本的图片预加载效果,简单对大妈做一下说明:
(1).preloadimages(arr),参数是存放图片地址的数组,也可以是单个地址(当然这时候不是数组)。
(2).var newimages=[],声明一个数组用来存储图片地址。
(3).var arr=(typeof arr!="object")? [arr] : arr,判断是不是一个数组,不是那么就人为的包装成一个数组,否则直接返回数组。
(4).for (var index=0; index<arr.length; index++){},使用for循环遍历数组中的每一个元素,也就是图片地址。
(5).newimages[index]=new Image(),创建一个Image对象。
(6).newimages[index].src=arr[index],设置对应图片对象的src属性,也就是是图片的地址。
简单的使用代码:
preloadimages(['one.gif', 'two.gif', 'three.gif'])
上面只是最基本的图片预加载,但是它往往在实际应用中有所欠缺,通常我们需要确切的知道图片什么时候加载完毕,然后再去干一些需要的事情,可以通过onload事件实现,代码修改如下:
function preloadimages(arr){ var newimages=[], loadedimages=0 var arr=(typeof arr!="object")? [arr] : arr function imageloadpost(){ loadedimages++ if (loadedimages==arr.length){ alert("图片已经加载完成") } } for (var index=0; index<arr.length; index++){ newimages[index]=new Image() newimages[index].src=arr[index] newimages[index].onload=function(){ imageloadpost() } newimages[index].onerror=function(){ imageloadpost() } } }
上面的代码中,当图片全部加载完成(成功或失败)后,浏览器将会弹出“图片已经加载完成”的消息。
现在,将为preloadimages()函数增加一个回调函数来处理后续的操作,通常会为我们的preloadimages()函数增加一个匿名函数做为参数,来完成我们需要的功能。如此之后,我们调用preloadimages()函数的代码可能会如下面这样。
preloadimages(imagesarray, function(){ //图片加载完成之后执行的操作 })
下面来做一点改变,让代码看起来更直观,更易于理解,改造完成之后,preloadimages()函数的调用看起来如下所示。
preloadimages(imagesarray).done(function(){ //图片加载完成后的操作 })
上面这种写法大家一看一定都会觉得非常清晰明了,那么接下来,继续来改造我们的preloadimages()函数。
function preloadimages(arr){ var newimages=[], loadedimages=0 var postaction=function(){} //此处增加了一个postaction函数 var arr=(typeof arr!="object")? [arr] : arr function imageloadpost(){ loadedimages++ if (loadedimages==arr.length){ postaction(newimages) //加载完成用我们调用postaction函数并将newimages数组做为参数传递进去 } } for (var index=0; index<arr.length; index++){ newimages[index]=new Image() newimages[index].src=arr[index] newimages[index].onload=function(){ imageloadpost() } newimages[index].onerror=function(){ imageloadpost() } } return { //此处返回一个空白对象的done方法 done:function(f){ postaction=f || postaction } } }
上面的代码稍作修改了几个地方:
首先,增加了一个postaction函数,该函数被用来做为图片加载完成后的回调函数,用户可以在后面调用的时候用自己的处理函数覆盖掉该函数。
第二,preloadimages()函数返回了一个空对象,其中包含一个简单的done()方法,这是实现本次改造的关键所在,确保了链式调用的实现。
最后,调用变为如下形式:
preloadimages(['1.gif', '2.gif', '3.gif']).done(function(images){ alert(images.length) //alerts 3 alert(images[0].src+" "+images[0].width) //alerts '1.gif 220' })