圖片的預加載就是在加載大圖片前,先顯示一個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>
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>