Track Image Loading效果代碼分析
更新時(shí)間:2007年08月13日 19:13:36 作者:
目的
在圖片的加載過程中,提供定義圖片加載成功或加載失敗/超時(shí)時(shí)的回調(diào)函數(shù),并確保執(zhí)行。
動(dòng)機(jī)
原生JavaScript已經(jīng)對 Image 對象提供了 onload 和 onerror 注冊事件。但在瀏覽器緩存及其他因素的影響下,用戶在使用回退按鈕或者刷新頁面時(shí) onload 事件常常未能穩(wěn)定觸發(fā)。在我開發(fā)的相冊系統(tǒng)中,我希望圖片能根據(jù)自定義的大小顯示以免導(dǎo)致頁面變形,例如最寬不得超過500px,而小于500px寬度的圖片則按原大小顯示。CSS2 提供了 max-width 屬性能夠幫組我們實(shí)現(xiàn)這一目的。但很遺憾,挨千刀的IE6并不支持。
IE6一個(gè)彌補(bǔ)的辦法就是通過注冊 img.onload 事件,待圖片加載完成后自動(dòng)調(diào)整大小。以下代碼取自著名的Discuz!論壇系統(tǒng)4.1版本對顯示圖片的處理。
<img src="http://img8.imagepile.net/img8/47104p155.jpg" border="0"
onload="if(this.width>screen.width*0.7) {this.resized=true; this.width=screen.width*0.7;
this.alt='Click here to open new windownCTRL+Mouse wheel to zoom in/out';}"
onmouseover="if(this.width>screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.style.cursor='hand'; this.alt='Click here to open new windownCTRL+Mouse wheel to zoom in/out';}"
onclick="if(!this.resized) {return true;} else {window.open('http://img8.imagepile.net/img8/47104p155.jpg');}"
onmousewheel="return imgzoom(this);">
前文已述,瀏覽器并不保證事件處理函數(shù)執(zhí)行。所以需要一個(gè)更穩(wěn)定的方式跟蹤圖片加載過程,并執(zhí)行設(shè)定的回調(diào)函數(shù)。
實(shí)現(xiàn)
image.complete 屬性標(biāo)示的是圖片加載狀態(tài),其值如果為ture,則表示加載成功。圖片不存在或加載超時(shí)則值為false。利用 setInterval() 函數(shù)定時(shí)檢查該狀態(tài)則可以實(shí)現(xiàn)跟蹤圖片加載的狀況。代碼片斷如下:
ImageLoader = Class.create();
ImageLoader.prototype = {
initialize : function(options) {
this.options = Object.extend({
timeout: 60, //60s
onInit: Prototype.emptyFunction,
onLoad: Prototype.emptyFunction,
onError: Prototype.emptyFunction
}, options || {});
this.images = [];
this.pe = new PeriodicalExecuter(this._load.bind(this), 0.02);
},
........
}
利用Prototype 的PeriodicalExecuter類創(chuàng)建一個(gè)定時(shí)器,每隔20毫秒檢查一次圖片的加載情況,并根據(jù)狀態(tài)執(zhí)行 options 參數(shù)中定義的回調(diào)函數(shù)。
使用
var loader = new ImageLoader({
timeout: 30,
onInit: function(img) {
img.style.width = '100px';
},
onLoad: function(img) {
img.style.width = '';
if (img.width > 500)
img.style.width = '500px';
},
onError: function(img) {
img.src = 'error.jpg'; //hint image
}
});loader.loadImage(document.getElementsByTagName('img'));
上面的代碼定義圖片最初以100px顯示,加載成功后如果圖片實(shí)際寬度超過500px,則再強(qiáng)制定義為500px,否則顯示原大小。如果圖片不存在或加載超時(shí)(30秒為超時(shí)),則顯示錯(cuò)誤圖片。
同理,可以應(yīng)用 ImageLoader 的回調(diào)函數(shù)來根據(jù)需求自定義效果,例如默認(rèn)顯示loading,加載完成后再顯示原圖;圖片首先灰度顯示,加載完成后再恢復(fù)亮度等等。例如:
//need scriptaculous effects.js
var loader = new ImageLoader({
onInit: function(img) {
Element.setOpacity(img, 0.5); //默認(rèn)5級透明
},
onLoad: function(img) {
Effect.Appear(img); //恢復(fù)原圖顯示
}
});
附示例中包含完整的代碼及使用pconline圖片為例的測試, 注意 范例中使用了最新的Prototype 1.5.0_rc1。
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 //EN">
<html>
<head>
<script src="prototype1.5.0_rc1.js"></script>
<script src="validation1.5.3/effects.js"></script>
</head>
<body>
<img id="img0" src="http://img.pconline.com.cn/images/photoblog/2026024/20069/14/1158169144171.jpg" />
<img id="img1" src="http://img.pconline.com.cn/images/photoblog/2026024/20069/14/1158169158366.jpg" />
<img id="img2" src="http://img.pconline.com.cn/images/photoblog/2026024/20069/14/1158169169983_mthumb.jpg" />
<br />加載失敗測試<br />
<img id="img2" src="http://img.pconline.com.cn/images/photoblog/2026024/20069/14/000000000000.jpg" />
<script type="text/javascript">
ImageLoader = Class.create();
ImageLoader.prototype = {
initialize : function(options) {
this.options = Object.extend({
timeout: 60, //60s
onInit: Prototype.emptyFunction,
onLoad: Prototype.emptyFunction,
onError: Prototype.emptyFunction
}, options || {});
this.images = [];
this.pe = new PeriodicalExecuter(this._load.bind(this), 0.02);
},
loadImage : function() {
var self = this;
$A(arguments).each(function(img) {
if (typeof(img) == 'object')
$A(img).each(self._addImage.bind(self));
else
self._addImage(img);
});
},
_addImage : function(img) {
img = $(img);
img.onerror = this._onerror.bind(this, img);
this.options.onInit.call(this, img);
if (this.options.timeout > 0) {
setTimeout(this._ontimeout.bind(this, img), this.options.timeout*1000);
}
this.images.push(img);
if (!this.pe.timer)
this.pe.registerCallback();
},
_load: function() {
this.images = this.images.select(this._onload.bind(this));
if (this.images.length == 0) {
this.pe.stop();
}
},
_checkComplete : function(img) {
if (img._error) {
return true;
} else {
return img.complete;
}
},
_onload : function(img) {
if (this._checkComplete(img)) {
this.options.onLoad.call(this, img);
img.onerror = null;
if (img._error)
try {delete img._error}catch(e){}
return false;
}
return true;
},
_onerror : function(img) {
img._error = true;
img.onerror = null;
this.options.onError.call(this, img);
},
_ontimeout : function(img) {
if (!this._checkComplete(img)) {
this._onerror(img);
}
}
}
var loader = new ImageLoader({
timeout: 30,
onInit: function(img) {
img.style.width = '100px';
},
onLoad: function(img) {
img.style.width = '';
if (img.width > 500) {
img.style.width = '500px';
}
},
onError: function(img) {
img.src = 'http://img.pconline.com.cn/nopic.gif';
}
});
loader.loadImage(document.getElementsByTagName('img'));
/*
var loader = new ImageLoader({
timeout: 30,
onInit: function(img) {
Element.setOpacity(img, 0.5);
},
onLoad: function(img) {
Effect.Appear(img);
},
onError: function(img) {
img.src = 'http://img.pconline.com.cn/nopic.gif';
}
});
*/
/*
$A(document.getElementsByTagName('img')).each(
function(img) {
img.onload = function() {
img.style.width = '300px';
}
}
);
*/
</script>
</body>
</html>
在圖片的加載過程中,提供定義圖片加載成功或加載失敗/超時(shí)時(shí)的回調(diào)函數(shù),并確保執(zhí)行。
動(dòng)機(jī)
原生JavaScript已經(jīng)對 Image 對象提供了 onload 和 onerror 注冊事件。但在瀏覽器緩存及其他因素的影響下,用戶在使用回退按鈕或者刷新頁面時(shí) onload 事件常常未能穩(wěn)定觸發(fā)。在我開發(fā)的相冊系統(tǒng)中,我希望圖片能根據(jù)自定義的大小顯示以免導(dǎo)致頁面變形,例如最寬不得超過500px,而小于500px寬度的圖片則按原大小顯示。CSS2 提供了 max-width 屬性能夠幫組我們實(shí)現(xiàn)這一目的。但很遺憾,挨千刀的IE6并不支持。
IE6一個(gè)彌補(bǔ)的辦法就是通過注冊 img.onload 事件,待圖片加載完成后自動(dòng)調(diào)整大小。以下代碼取自著名的Discuz!論壇系統(tǒng)4.1版本對顯示圖片的處理。
<img src="http://img8.imagepile.net/img8/47104p155.jpg" border="0"
onload="if(this.width>screen.width*0.7) {this.resized=true; this.width=screen.width*0.7;
this.alt='Click here to open new windownCTRL+Mouse wheel to zoom in/out';}"
onmouseover="if(this.width>screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.style.cursor='hand'; this.alt='Click here to open new windownCTRL+Mouse wheel to zoom in/out';}"
onclick="if(!this.resized) {return true;} else {window.open('http://img8.imagepile.net/img8/47104p155.jpg');}"
onmousewheel="return imgzoom(this);">
前文已述,瀏覽器并不保證事件處理函數(shù)執(zhí)行。所以需要一個(gè)更穩(wěn)定的方式跟蹤圖片加載過程,并執(zhí)行設(shè)定的回調(diào)函數(shù)。
實(shí)現(xiàn)
image.complete 屬性標(biāo)示的是圖片加載狀態(tài),其值如果為ture,則表示加載成功。圖片不存在或加載超時(shí)則值為false。利用 setInterval() 函數(shù)定時(shí)檢查該狀態(tài)則可以實(shí)現(xiàn)跟蹤圖片加載的狀況。代碼片斷如下:
ImageLoader = Class.create();
ImageLoader.prototype = {
initialize : function(options) {
this.options = Object.extend({
timeout: 60, //60s
onInit: Prototype.emptyFunction,
onLoad: Prototype.emptyFunction,
onError: Prototype.emptyFunction
}, options || {});
this.images = [];
this.pe = new PeriodicalExecuter(this._load.bind(this), 0.02);
},
........
}
利用Prototype 的PeriodicalExecuter類創(chuàng)建一個(gè)定時(shí)器,每隔20毫秒檢查一次圖片的加載情況,并根據(jù)狀態(tài)執(zhí)行 options 參數(shù)中定義的回調(diào)函數(shù)。
使用
var loader = new ImageLoader({
timeout: 30,
onInit: function(img) {
img.style.width = '100px';
},
onLoad: function(img) {
img.style.width = '';
if (img.width > 500)
img.style.width = '500px';
},
onError: function(img) {
img.src = 'error.jpg'; //hint image
}
});loader.loadImage(document.getElementsByTagName('img'));
上面的代碼定義圖片最初以100px顯示,加載成功后如果圖片實(shí)際寬度超過500px,則再強(qiáng)制定義為500px,否則顯示原大小。如果圖片不存在或加載超時(shí)(30秒為超時(shí)),則顯示錯(cuò)誤圖片。
同理,可以應(yīng)用 ImageLoader 的回調(diào)函數(shù)來根據(jù)需求自定義效果,例如默認(rèn)顯示loading,加載完成后再顯示原圖;圖片首先灰度顯示,加載完成后再恢復(fù)亮度等等。例如:
//need scriptaculous effects.js
var loader = new ImageLoader({
onInit: function(img) {
Element.setOpacity(img, 0.5); //默認(rèn)5級透明
},
onLoad: function(img) {
Effect.Appear(img); //恢復(fù)原圖顯示
}
});
附示例中包含完整的代碼及使用pconline圖片為例的測試, 注意 范例中使用了最新的Prototype 1.5.0_rc1。
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 //EN">
<html>
<head>
<script src="prototype1.5.0_rc1.js"></script>
<script src="validation1.5.3/effects.js"></script>
</head>
<body>
<img id="img0" src="http://img.pconline.com.cn/images/photoblog/2026024/20069/14/1158169144171.jpg" />
<img id="img1" src="http://img.pconline.com.cn/images/photoblog/2026024/20069/14/1158169158366.jpg" />
<img id="img2" src="http://img.pconline.com.cn/images/photoblog/2026024/20069/14/1158169169983_mthumb.jpg" />
<br />加載失敗測試<br />
<img id="img2" src="http://img.pconline.com.cn/images/photoblog/2026024/20069/14/000000000000.jpg" />
<script type="text/javascript">
ImageLoader = Class.create();
ImageLoader.prototype = {
initialize : function(options) {
this.options = Object.extend({
timeout: 60, //60s
onInit: Prototype.emptyFunction,
onLoad: Prototype.emptyFunction,
onError: Prototype.emptyFunction
}, options || {});
this.images = [];
this.pe = new PeriodicalExecuter(this._load.bind(this), 0.02);
},
loadImage : function() {
var self = this;
$A(arguments).each(function(img) {
if (typeof(img) == 'object')
$A(img).each(self._addImage.bind(self));
else
self._addImage(img);
});
},
_addImage : function(img) {
img = $(img);
img.onerror = this._onerror.bind(this, img);
this.options.onInit.call(this, img);
if (this.options.timeout > 0) {
setTimeout(this._ontimeout.bind(this, img), this.options.timeout*1000);
}
this.images.push(img);
if (!this.pe.timer)
this.pe.registerCallback();
},
_load: function() {
this.images = this.images.select(this._onload.bind(this));
if (this.images.length == 0) {
this.pe.stop();
}
},
_checkComplete : function(img) {
if (img._error) {
return true;
} else {
return img.complete;
}
},
_onload : function(img) {
if (this._checkComplete(img)) {
this.options.onLoad.call(this, img);
img.onerror = null;
if (img._error)
try {delete img._error}catch(e){}
return false;
}
return true;
},
_onerror : function(img) {
img._error = true;
img.onerror = null;
this.options.onError.call(this, img);
},
_ontimeout : function(img) {
if (!this._checkComplete(img)) {
this._onerror(img);
}
}
}
var loader = new ImageLoader({
timeout: 30,
onInit: function(img) {
img.style.width = '100px';
},
onLoad: function(img) {
img.style.width = '';
if (img.width > 500) {
img.style.width = '500px';
}
},
onError: function(img) {
img.src = 'http://img.pconline.com.cn/nopic.gif';
}
});
loader.loadImage(document.getElementsByTagName('img'));
/*
var loader = new ImageLoader({
timeout: 30,
onInit: function(img) {
Element.setOpacity(img, 0.5);
},
onLoad: function(img) {
Effect.Appear(img);
},
onError: function(img) {
img.src = 'http://img.pconline.com.cn/nopic.gif';
}
});
*/
/*
$A(document.getElementsByTagName('img')).each(
function(img) {
img.onload = function() {
img.style.width = '300px';
}
}
);
*/
</script>
</body>
</html>
相關(guān)文章
bootstrap-table獲取表格數(shù)據(jù)的多種方式
這篇文章主要介紹了bootstrap-table獲取表格數(shù)據(jù)的多種方式,bootstrap-table獲取值得兩種方式,一種是通過data獲取,一種是通過url獲取,需要的朋友可以參考下2023-10-10uniapp項(xiàng)目實(shí)踐自定義加載組件示例詳解
這篇文章主要為大家介紹了uniapp項(xiàng)目實(shí)踐自定義加載組件示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-09-09微信小程序?qū)崿F(xiàn)pdf、word等格式文件上傳的方法
這篇文章主要介紹了微信小程序?qū)崿F(xiàn)pdf,word等格式文件上傳的方法,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-09-09JavaScript實(shí)現(xiàn)左側(cè)菜單效果
這篇文章主要為大家詳細(xì)介紹了JavaScript實(shí)現(xiàn)左側(cè)菜單效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-12-12