虚拟代理实现图片预加载


在web开发中,图片预加载是一种很常用的技术。

如果给一个img标签节点设置src属性,图片体积过大,或者网路不佳的情况下,往往会有比较长时间的空白,体验不好。

虚拟代理实现图片预加载_第1张图片
556D0667-BD7C-4B27-BA16-74D05067DEE8.png

常见的做法是先用一张loading图占位,然后异步的方式加载图片。等图片加载好了再填充到img节点里。


var myImage = (function(){

var imgNode = document.createElement('img');
document.body.appendChild(imgNode) ;
var img = new Image ;
img.onload = function() {
imgNode.src = img.src ;
}
return { setSrc : function(src){
imgNode.src = '../testImages/7.jpg' ; }
}})();
myImage.setSrc('../testImages/7.jpg');

上面的一段代码,myImage 对象 除了负责给img节点 设置src,还要负责预加载图片。
在面向对象设计中,如果一个对象承担了多项职责,就意味着这个对象可能会变的巨大。//我就见到过一个函数好几百行。。。

面向对象设计 鼓励把行为分开,分散为更细粒度的对象之中。
原因显而易见,如果一个对象承担的职责过多,耦合性会很高,这种耦合会导致脆弱和低内聚的设计,容易发生意外。

现在回到代码中去, 如果我们只是加载体积不大的图,若干年后网络足够快,我们不在需要预加载了,要想把这段代码删掉,这时候就不得不改动myimage对象了。

实际上,我们需要做的只是给img 设置src,如果能把这个操作放到另一个对象中去操作,那当然是极好的。
下面我们重构一下这段代码:


var myImage = (function(){
var imageNode = document.createElement('img');
document.body.appendChild(imageNode) ;
return {
setSrc : function(src){
imageNode.src = src ;
}
}})();

var proxyImage = (function(){
var img = new Image;
img.onload = function(){
myImage.setSrc( this.src);
}
return {
setSrc : function (src){
myImage.setSrc('../testImages/loading.gif');
img.src = src ;
}
}})();

proxyImage.setSrc('../testImages/1.jpg');

现在我们通过proxyImage间接的访问myImage。
proxyImage控制了客户对myImage 的访问,而且在这个过程中还能加入一些其他的操作,比如图片加载完成之前,显示loading图,体验会好一些。

虚拟代理实现图片预加载_第2张图片

小结:
通过代理对象,添加了新的行为,符合开放-封闭 原则。
给img 节点设置src 和图片 预加载这两个功能被隔离开到两个对象里,
他们可以各自变化 而不影响到另一个,这个是很重要的。
况且,加入有一天我们不需要这个预加载了,那只需要改变请求体 而不是请求代理对象就好了。

你可能感兴趣的:(虚拟代理实现图片预加载)