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'
})
一线大厂高级前端编写,前端初中阶面试题,帮助初学者应聘,需要联系微信:javadudu

回复

我来回复
  • 暂无回复内容