代理模式是为其他对象提供一种代理以控制对这个对象的访问。
需要实现图片的预加载是因为当页面中的图片较大或网络不佳时,图片的位置可能会是一片空白,可能还会影响页面布局,因此通常都是用一张loading图片占位,等图片加载完成立即填充到img节点里,最近学习到了使用JavaScript代理模式来实现图片预加载。
在html的body中放置几个img:
<img src="">
<img src="">
<img src="">
javascript代码:
首先创建一个普通的本体对象,这个对象负责获取页面中的div元素,并且提供对外的setSrc接口,通过这个接口可以给所有的img设置src属性:
var myImage=(function(){
var imgNode=document.getElementsByTagName("img");//获取页面中的所有img
return {
setSrc:function(src){
var arg=[].slice.call(arguments);//将传入的参数转为数组
for(var i=0;i<imgNode.length;i++){
if(arg.length==1){//如果只有一个实参,判断该参数是否为数组
//如果该参数为数组,则将数组内每一个src赋给对应的img
if(Object.prototype.toString.call(arg[0])=="[object Array]"){
imgNode[i].src=arg[0][i];
}
//如果不是数组,则直接将该参数赋给每一个img
else{
imgNode[i].src=arg[0];
}
}
else{
imgNode[i].src=arg[i];
}
}
}
}
})();
接下来创建一个代理对象proxyImage,通过这个代理对象,同样提供一个setSrc接口,在图片加载好之前,都先用一个loading.gif图片占位,提示用户图片正在加载:
var proxyImage=(function(){
var img=new Image;
var source=[];//保存每一个需要加载的图片
img.onload=function(){//图片加载完成时调用函数
console.log("加载成功!");
myImage.setSrc(source);//将数组传递给myImage.setSrc
}
return {
setSrc:function(src){
myImage.setSrc("loading.gif");//预加载loading.gif
for(var i=0;i<arguments.length;i++){
img.src=arguments[i];//设置要加载的图片的src
source.push(arguments[i]);//将每一个参数都传入数组内
}
}
}
})();
接下来调用这个代理对象:
proxyImage.setSrc("http://7xsb8q.com1.z0.glb.clouddn.com/css1.JPG","http://7xsb8q.com1.z0.glb.clouddn.com/css2.JPG","http://7xsb8q.com1.z0.glb.clouddn.com/css3.JPG");
代理对象负责预加载图片,在预加载的操作完成之后,把请求又重新交给本体myImage。同时我们也并没有改变myImage的接口,给img设置src和图片预加载两个功能被隔离在两个对象里,它们可以各自变化而不影响对方,即使有一天不需要预加载,只需要改成直接请求本体对象即可。
学习资料:
《JavaScript设计模式与开发实践》——曾探