久久男人AV资源网站无码_乱人伦人妻精品一区二区_亚洲国产精久久久久久久_狠狠躁夜夜躁人人爽天天BL

談談javascript的圖片預加載技術

2014-04-17 宇易網絡 2809

lightbox類效果為了讓(rang)圖片居(ju)中顯(xian)示而使用預(yu)加(jia)載(zai),需(xu)要等待完(wan)(wan)全(quan)加(jia)載(zai)完(wan)(wan)畢才能顯(xian)示,體驗不佳

(如filick相冊的(de)全屏效果(guo))。javascript無(wu)法獲取img文(wen)件頭數據,真(zhen)的(de)是這(zhe)樣嗎?

本文通過一個巧(qiao)妙的方法讓javascript獲取它。

這是大(da)部分人使用(yong)預(yu)加載獲取圖片大(da)小的例子:


var imgLoad = function (url, callback) {
var img = new Image();
 
img.src = url;
if (img.complete) {
callback(img.width, img.height);
} else {
img.onload = function () {
callback(img.width, img.height);
img.onload = null;
};
};
 
};

可以看(kan)到上面必須(xu)等待圖片(pian)加(jia)載完畢才能獲取尺寸,其速(su)度不敢(gan)恭維(wei),我們需要改進。

web應(ying)用程序區(qu)別于桌面應(ying)用程序,響應(ying)速(su)度才(cai)是最好的用戶體驗。如果想要速(su)度與優雅兼得,那(nei)就必須提前獲得圖片(pian)尺寸,如何在(zai)圖片(pian)沒有(you)加(jia)載(zai)完畢就能獲取圖片(pian)尺寸?

十多年(nian)的(de)(de)上網經驗告訴我:瀏覽器在加載圖(tu)片(pian)的(de)(de)時候你(ni)會看到(dao)圖(tu)片(pian)會先占用一塊地然(ran)后才(cai)慢(man)慢(man)加載完畢,并且不需(xu)要(yao)預(yu)設width與height屬性,因為瀏覽器能(neng)夠(gou)獲(huo)取圖(tu)片(pian)的(de)(de)頭部數據(ju)。基(ji)于此(ci),只需(xu)要(yao)使用javascript定(ding)時偵測圖(tu)片(pian)的(de)(de)尺(chi)寸狀(zhuang)態便可得知圖(tu)片(pian)尺(chi)寸就緒的(de)(de)狀(zhuang)態。

當然實際(ji)中(zhong)會有(you)一些(xie)兼容(rong)陷阱,如width與height檢測各個瀏覽(lan)器的不一致,還有(you)webkit new Image()建(jian)立的圖片會受以處(chu)在加載進(jin)程中(zhong)同url圖片影(ying)響,經過反復測試后的最佳處(chu)理方(fang)式:

// 更新:
// 05.27: 1、保證回調執行順序:error > ready > load;2、回調函數this指向img本身
// 04-02: 1、增加圖片完全加載后的回調 2、提高性能
 
/**
* 圖片頭數據加載就緒事件 - 更快獲取圖片尺寸
* @version    2011.05.27
* @author    TangBin
* @see        //www.planeart.cn/?p=1121
* @param    {String}    圖片路徑
* @param    {Function}    尺寸就緒
* @param    {Function}    加載完畢 (可選)
* @param    {Function}    加載錯誤 (可選)
* @example imgReady('//www.google.com.hk/intl/zh-CN/images/logo_cn.png', function () {
alert('size ready: width=' + this.width + '; height=' + this.height);
});
*/
var imgReady = (function () {
var list = [], intervalId = null,
 
// 用來執行隊列
tick = function () {
var i = 0;
for (; i < list.length; i++) {
list[i].end ? list.splice(i--, 1) : list[i]();
};
!list.length && stop();
},
 
// 停止所有定時器隊列
stop = function () {
clearInterval(intervalId);
intervalId = null;
};
 
return function (url, ready, load, error) {
var onready, width, height, newWidth, newHeight,
img = new Image();
 
img.src = url;
 
// 如果圖片被緩存,則直接返回緩存數據
if (img.complete) {
ready.call(img);
load && load.call(img);
return;
};
 
width = img.width;
height = img.height;
 
// 加載錯誤后的事件
img.onerror = function () {
error && error.call(img);
onready.end = true;
img = img.onload = img.onerror = null;
};
 
// 圖片尺寸就緒
onready = function () {
newWidth = img.width;
newHeight = img.height;
if (newWidth !== width || newHeight !== height ||
// 如果圖片已經在其他地方加載可使用面積檢測
newWidth * newHeight > 1024
) {
ready.call(img);
onready.end = true;
};
};
onready();
 
// 完全加載完畢的事件
img.onload = function () {
// onload在定時器時間差范圍內可能比onready快
// 這里進行檢查并保證onready優先執行
!onready.end && onready();
 
load && load.call(img);
 
// IE gif動畫會循環執行onload,置空onload即可
img = img.onload = img.onerror = null;
};
 
// 加入隊列中定期執行
if (!onready.end) {
list.push(onready);
// 無論何時只允許出現一個定時器,減少瀏覽器性能損耗
if (intervalId === null) intervalId = setInterval(tick, 40);
};
};
})();
調用例子:


imgReady('//www.google.com.hk/intl/zh-CN/images/logo_cn.png', function () {
alert('size ready: width=' + this.width + '; height=' + this.height);
});

是不是很簡單?這樣的方式獲取攝影級別照片尺寸的速度往往是onload方式的幾十多倍,而對于web普通(800×600內)瀏覽級別的圖片能達到秒殺效果。看了這個再回憶一下你見過的web相冊,是否絕大部分都可以重構一下呢?好了,



相關文章

展開
聯系電話: 客服QQ: