javascript设计模式实践之代理模式--图片预加载
图片的预加载就是在加载大图片前,先显示一个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设计模式实践之代理模式--图片预加载的更多相关文章
- javascript设计模式学习之六——代理模式
一.代理模式定义 代理模式的关键是:当客户不方便直接访问一个对象或者不满足需要的时候,提供一个替身对象来控制对这个对象的访问.代理模式需要和本体对外提供相同的接口,对用户来说是透明的.代理模式的种类有 ...
- Javascript图片预加载详解
预加载图片是提高用户体验的一个很好方法.图片预先加载到浏览器中,访问者便可顺利地在你的网站上冲浪,并享受到极快的加载速度.这对图片画廊及图片占据很大比例的网站来说十分有利,它保证了图片快速.无缝地发布 ...
- 利用CSS、JavaScript及Ajax实现图片预加载的三大方法
预加载图片是提高用户体验的一个很好方法.图片预先加载到浏览器中,访问者便可顺利地在你的网站上冲浪,并享受到极快的加载速度.这对图片画廊及图片占据很大比例的网站来说十分有利,它保证了图片快速.无缝地发布 ...
- 利用CSS、JavaScript及Ajax实现图片预加载的三大方法(转)
预加载图片是提高用户体验的一个很好方法.图片预先加载到浏览器中,访问者便可顺利地在你的网站上冲浪,并享受到极快的加载速度.这对图片画廊及图片占据很大比例的网站来说十分有利,它保证了图片快速.无缝地发布 ...
- Javascript图片预加载详解 分类: JavaScript HTML+CSS 2015-05-29 11:01 768人阅读 评论(0) 收藏
预加载图片是提高用户体验的一个很好方法.图片预先加载到浏览器中,访问者便可顺利地在你的网站上冲浪,并享受到极快的加载速度.这对图片画廊及图片占据很大比例的网站来说十分有利,它保证了图片快速.无缝地发布 ...
- 利用CSS、JavaScript及Ajax实现图片预加载的三大方法及优缺点分析
预加载图片是提高用户体验的一个很好方法.图片预先加载到浏览器中,访问者便可顺利地在你的网站上冲浪,并享受到极快的加载速度.这对图片画廊及图片占据很大比例的网站来说十分有利,它保证了图片快速.无缝地发布 ...
- Javascript兑现图片预加载【回调函数,多张图片】 (转载)
Javascript实现图片预加载[回调函数,多张图片] 使用JS实现一组图片动画效果或者使用HTML5 Canvas渲染一系列图片等案例中,需要图片全部加载完成方可运行动画效果.此时程序中就会涉及多 ...
- 再谈javascript图片预加载技术
图片预加载技术的典型应用: 如lightbox方式展现照片,无疑需要提前获得大图的尺寸,这样才能居中定位,由于javascript无法获取img文件头数据,必须等待其加载完毕后才能获取真实的大小然后展 ...
- javascript 图片预加载
<!DOCTYPE > <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta ...
随机推荐
- angular中的MVVM模式
在开始介绍angular原理之前,我们有必要先了解下mvvm模式在angular中运用.虽然在angular社区一直将angular统称为前端MVC框架,同时angular团队也称它为MVW(What ...
- 十进制数转化成二进制后包含一的数量(c++)
#include <iostream> using namespace std;int func(int x){ int count=0; while(x){ ...
- AlwaysON 故障处理之辅助副本磁盘空间不足
用户反馈AlwaysON辅助副本数据库查询的结果与主库不一致, 远程到服务器后发现数据库的状态显示为“未同步/可疑”, 查看数据库的日志,定位到出现错误的时间点,可以看到提示日志文件所在磁盘的“磁盘空 ...
- Senparc.Weixin.MP SDK 微信公众平台开发教程(五):使用Senparc.Weixin.MP SDK
Senparc.Weixin.MP SDK已经涵盖了微信6.x的所有公共API. 整个项目的源代码以及已经编译好的程序集可以在这个项目中获取到:https://github.com/JeffreySu ...
- navigationController pop的几种方法
一,popViewControllerAnimated [self.navigationController popViewControllerAnimated:YES]; 二,popToRootVi ...
- 第九回 Microsoft.Practices.Unity.Interception实现基于数据集的缓存(针对六,七,八讲的具体概念和配置的解说)
返回目录 概念 Microsoft.Practices.Unity.Interception是一个拦截器,它隶属于Microsoft.Practices.Unity组成之中,主要完成AOP的功能,而实 ...
- Atitit intellij idea的使用总结attilax
Atitit intellij idea的使用总结attilax 1. ideaIC-2016.2.4.exe1 1.1. Ij vs eclipse市场份额1 1.2. Ij的优点(方便的支持gro ...
- fir.im Weekly - 从零开始创建 Android 新项目
今年的 Google I/O 大会上,人工智能和虚拟现实的产品发布让我们对未来多了几分惊喜.对于开发者部分,Google 发布了 Android N 系统,感受最深的是全新的 Android Stud ...
- SSIS package 更新 variable
在Package中声明一个variable,在package运行的过程中,SSIS如何update Variable? 第一种方法:使用 Script Task 来更新Variable的值 1,创建一 ...
- 深入理解CSS元素可见性visibility
× 目录 [1]定义 [2]属性 [3]display[4]JS[5]transition [6]API[7]DEMO 前面的话 visibility属性常见于与display属性的比较中.但实际上, ...