图片的预加载就是在加载大图片前,先显示一个loading.gif,就算在网络比较慢的时候也能让人知道正在加载,总比啥反应都没有强。

下面这段代码就是预加载的一个简单的实现,假设先不处理加载图片时的onError,onAbort,超时的问题。

只关注代码的结构。

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<button id='btnLoadImg'>加载图片</button>
<br>
<div id='imgContainer'>
</div>
<br> <script type='text/javascript' src="./jquery-1.11.3.min.js"></script>
<script type='text/javascript'>
$(document).ready(function(){
$('#btnLoadImg').bind('click', doLoadImg);
}); function doLoadImg(){ var eleImg = createImgElement();
document.getElementById('imgContainer').appendChild(eleImg); loadImg(eleImg, 'http://img.wanchezhijia.com/A/2015/3/20/17/11/de63f77c-f74f-413a-951b-5390101a7d74.jpg');
} //创建img标签
//这里用自执行函数加一个闭包,是为了可以创建多个id不同的img标签。
var createImgElement = (function(){
var index = 0; return function() {
var eleImg = document.createElement('img');
eleImg.setAttribute('width', '200');
eleImg.setAttribute('heght', '150');
eleImg.setAttribute('id', 'img' + index++);
return eleImg;
};
})(); //预加载图片
//给img标签设一个加载图片,通过Image对象预先加载实际图片加载完成后设到img标签上
function loadImg(img, src) {
var imgCache = new Image();
imgCache.onload = function(){
img.src = this.src;
}; img.src = 'loading.gif';
imgCache.src = src;
} </script>
</body>
</html>

以下预加载的代码功能上是满足了,但是它的职责包含了预加载和加载两个职责,违反了“单一职责原则”。所谓的职责就是“会发生的变化”,如果网速的问题不再是问题或者加载的图片的分辨率被控制在很小的时候等,需要去掉预加载的功能,这时候就要修改loadImg的代码,就要重新跑所有相关的测试,即违反了“开闭原则”,又增加测试工作。

            function loadImg(img, src) {
var imgCache = new Image();
imgCache.onload = function(){
img.src = this.src;
}; img.src = 'loading.gif';
imgCache.src = src;
}

加载和预加载其实就是代理模式的一种,代理模式可以理解成,你会开车但是因为某种原因只能找人代理开车,因为不了解MM的喜好找人代理送花。

将预加载功能改成代理模式可以理解成:本体先显示个门面,找代理去加载,加载完了,告诉本体,本体把图片贴上去就行了。

既然如此,本体的职责就很简单了,就往门面上贴。

加载本体函数:

            function loadImg(img, src) {
img.src = src;
}

做一个预加载代理函数:

            function loadImgProxy(img, src){
var imgCache = new Image();
imgCache.onload = function(){
loadImg(img, this.src);
}; loadImg(img, 'loading.gif');
imgCache.src = src;
}

在代理函数中,先让本体加载loading.gif,等大图加载完了再让本体加载实际图片。

代理还是和本体函数的接口参数是一致的,职责分的比较清晰,如果到时候要把预加载去掉,也不需要修改本体和代理的代码,只需要在调用的地方把代理的名字换成本体的名字即可。

可以适当的把代理函数改一下,可以让其适应加载多个图片的场景,其实就是做一个闭包,把缓存Image对象变成私有即可:

            var loadImgProxy = (function(){
var imgCache = new Image(); return function(img, src){
imgCache.onload = function(){
loadImg(img, this.src);
}; loadImg(img, 'loading.gif');
imgCache.src = src;
};
})();

修改后的完整代码:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<button id='btnLoadImg'>加载图片</button>
<br>
<div id='imgContainer'>
</div>
<br> <script type='text/javascript' src="./jquery-1.11.3.min.js"></script>
<script type='text/javascript'>
$(document).ready(function(){
$('#btnLoadImg').bind('click', doLoadImg);
}); function doLoadImg(){ var eleImg = createImgElement();
document.getElementById('imgContainer').appendChild(eleImg);

//使用代理函数进行加载
//如果某一天不需要预加载了,就把loadImgProxy换成loadImg即可
loadImgProxy(eleImg, 'http://img.wanchezhijia.com/A/2015/3/20/17/11/de63f77c-f74f-413a-951b-5390101a7d74.jpg');
} //创建img标签
//这里用自执行函数加一个闭包,是为了可以创建多个id不同的img标签。
var createImgElement = (function(){
var index = 0; return function() {
var eleImg = document.createElement('img');
eleImg.setAttribute('width', '200');
eleImg.setAttribute('heght', '150');
eleImg.setAttribute('id', 'img' + index++);
return eleImg;
};
})();

//加载图片本体函数
function loadImg(img, src) {
img.src = src;
}
//加载图片代理函数
var loadImgProxy = (function(){
var imgCache = new Image(); return function(img, src){
imgCache.onload = function(){
loadImg(img, this.src);
}; loadImg(img, 'loading.gif');
imgCache.src = src;
};
})(); </script>
</body>
</html>

javascript设计模式实践之代理模式--图片预加载的更多相关文章

  1. javascript设计模式学习之六——代理模式

    一.代理模式定义 代理模式的关键是:当客户不方便直接访问一个对象或者不满足需要的时候,提供一个替身对象来控制对这个对象的访问.代理模式需要和本体对外提供相同的接口,对用户来说是透明的.代理模式的种类有 ...

  2. Javascript图片预加载详解

    预加载图片是提高用户体验的一个很好方法.图片预先加载到浏览器中,访问者便可顺利地在你的网站上冲浪,并享受到极快的加载速度.这对图片画廊及图片占据很大比例的网站来说十分有利,它保证了图片快速.无缝地发布 ...

  3. 利用CSS、JavaScript及Ajax实现图片预加载的三大方法

    预加载图片是提高用户体验的一个很好方法.图片预先加载到浏览器中,访问者便可顺利地在你的网站上冲浪,并享受到极快的加载速度.这对图片画廊及图片占据很大比例的网站来说十分有利,它保证了图片快速.无缝地发布 ...

  4. 利用CSS、JavaScript及Ajax实现图片预加载的三大方法(转)

    预加载图片是提高用户体验的一个很好方法.图片预先加载到浏览器中,访问者便可顺利地在你的网站上冲浪,并享受到极快的加载速度.这对图片画廊及图片占据很大比例的网站来说十分有利,它保证了图片快速.无缝地发布 ...

  5. Javascript图片预加载详解 分类: JavaScript HTML+CSS 2015-05-29 11:01 768人阅读 评论(0) 收藏

    预加载图片是提高用户体验的一个很好方法.图片预先加载到浏览器中,访问者便可顺利地在你的网站上冲浪,并享受到极快的加载速度.这对图片画廊及图片占据很大比例的网站来说十分有利,它保证了图片快速.无缝地发布 ...

  6. 利用CSS、JavaScript及Ajax实现图片预加载的三大方法及优缺点分析

    预加载图片是提高用户体验的一个很好方法.图片预先加载到浏览器中,访问者便可顺利地在你的网站上冲浪,并享受到极快的加载速度.这对图片画廊及图片占据很大比例的网站来说十分有利,它保证了图片快速.无缝地发布 ...

  7. Javascript兑现图片预加载【回调函数,多张图片】 (转载)

    Javascript实现图片预加载[回调函数,多张图片] 使用JS实现一组图片动画效果或者使用HTML5 Canvas渲染一系列图片等案例中,需要图片全部加载完成方可运行动画效果.此时程序中就会涉及多 ...

  8. 再谈javascript图片预加载技术

    图片预加载技术的典型应用: 如lightbox方式展现照片,无疑需要提前获得大图的尺寸,这样才能居中定位,由于javascript无法获取img文件头数据,必须等待其加载完毕后才能获取真实的大小然后展 ...

  9. javascript 图片预加载

    <!DOCTYPE > <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta ...

随机推荐

  1. 源代码版本管理与项目管理软件的认识与github的注册

    源代码版本管理软件: 主要有:svn,cvs,hg,git,VSS 这些工具主要是一种记录代码更改历史, 可以无限回溯, 用于代码管理,多个程序员开发协作的工具.Perforce,StarTeam)- ...

  2. 【读书笔记】Html5游戏开发

    一直对HMTL5做游戏饶有兴趣,而这本书刚好就是HTML5 2游戏初级入门的书.Demo简单注释详细,可以拿来练练手,一个星期左右就可以读完.若要追求酷炫高大上效果,这本书恐怕要让你失望了.但作为上手 ...

  3. 相识Highcharts,几分钟玩转Highcharts

    Highcharts是一个功能强大.开源.美观.图表丰富.兼容绝大多数浏览器的纯js图表库. 官网:http://www.hcharts.cn/ 我觉得对于刚接触一个东西的新手来说,有时候对一个东西真 ...

  4. 依据BOM和已经存在的文件生成其他种类的文件

    在BOM中记录中有物料编码,物料名称,物料规格等,而且依据BOM已经生成了一些的文件,如采购规格书,这个时候需要生成相应的检验规格书模板,可以使用下面的VBA代码,具体代码如下: Function I ...

  5. 据说每个大牛、小牛都应该有自己的库——Ajax

    蹉跎到今天终于要写Ajax部分了,平时工作中除了选择器我用jQuery的最多的就是ajax,所以这部分在自己的框架中必不可少. XMLHttpRequest 我以为对每个使用过Ajax的人来说XMLH ...

  6. UWP 统一平台开发介绍

    什么是UWP? 很多程序员都有一个梦想:希望自己开发的软件能够轻而易举的在所有平台上运行,而不是把同样的需求,用不同的技术.工具重新开发才能够运行在所有平台上.这就是跨平台,很多软件从业者都在为这个梦 ...

  7. Linux常用命令(转)

    源自:http://www.linuxidc.com/Linux/2011-08/40437.htm Linux管理文件和目录的命令 命令 功能 命令 功能 pwd 显示当前目录 ls 查看目录下的内 ...

  8. Java中常量小知识

    常量分类:常量分为静态常量,非静态常量(全局常量),局部常量 静态常量:要么定义的时候赋初值,要么在静态代码块中赋值 非静态常量:要么在定义的时候赋初值,要么在代码块中赋值 局部常量:可以在定义时赋初 ...

  9. Js~动态判断PC和手机浏览器

    这个只是一个小知识,也是在网上找的,挺好用! 动态判断浏览器是PC还是移动端! <script> var browser={ versions:function(){ var u = na ...

  10. GridView和DATAGRID前后台查询用法的比较

    Grideview前台: <DIV class="mainDiv" id="GridWidth"> <ASP:GridView id=&quo ...