再談javascript圖片預加載技術

圖片預加載技術的典型應用javascript

如lightbox方式展示照片,無疑須要提早得到大圖的尺寸,這樣才能居中定位,因爲javascript沒法獲取img文件頭數據,必須等待其加載完畢後才能獲取真實的大小而後展現出來,因此lightbox顯示的圖片的速度體驗要比直接輸出的差不少,而本文說提到的預加載技術主要針對獲取圖片尺寸。css

一段典型的使用預加載獲取圖片大小的例子:html

 

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;
        };
    };
};

 

web應用程序區別於桌面應用程序,響應速度纔是最好的用戶體驗。若是想要速度與優雅兼得,那就必須提早得到圖片尺寸,如何在圖片沒有加載完畢就能獲取圖片尺寸?java

1、結合flash加載圖片,獲取圖片頭部數據的尺寸web

flash雖然很強大,但它與生俱來的缺點讓人愛恨交織,加上不少移動設備不支持falsh無疑更是致命的傷,仍是放棄吧。瀏覽器

2、在服務端保存圖片尺寸數緩存

這裏不得不提到騰訊Qzone的lightbox相冊,它就是這樣作的。它能在圖片沒有加載徹底的時候就居中放大圖片,速度與優雅基本兼得。不過它仍然難以免blog插入的外鏈圖片的問題,也只能按傳統的方式加載完畢才能展現。app

3、javascript經過佔位方式獲取圖片頭部數據的尺ide

十多年的上網經驗告訴我:瀏覽器在加載圖片的時候你會看到圖片會先佔用一塊地而後才慢慢加載完畢,而且這裏大部分的圖片都是沒有預設width與height屬性的,由於瀏覽器可以獲取圖片的頭部數據。基於此,只須要使用javascript定時偵測圖片的尺寸狀態即可得知圖片尺寸就緒的狀態。測試

實現代碼:

 

var imgReady = function (url, callback, error) {
    var width, height, intervalId, check, div,
        img = new Image(),
        body = document.body;
    img.src = url;
    // 從緩存中讀取
    if (img.complete) {
        return callback(img.width, img.height);
    };
    // 經過佔位提早獲取圖片頭部數據
    if (body) {
        div = document.createElement('div');
        div.style.cssText = 'visibility:hidden;position:absolute;left:0;top:0;width:1px;
height:1px;overflow:hidden';
        div.appendChild(img)
        body.appendChild(div);
        width = img.offsetWidth;
        height = img.offsetHeight;
        check = function () {
            if (img.offsetWidth !== width || img.offsetHeight !== height) {
                clearInterval(intervalId);
                callback(img.offsetWidth, img.clientHeight);
                img.onload = null;
                div.innerHTML = '';
                div.parentNode.removeChild(div);
            };
        };
        intervalId = setInterval(check, 150);
    };
    // 加載完畢後方式獲取
    img.onload = function () {
        callback(img.width, img.height);
        img.onload = img.onerror = null;
        clearInterval(intervalId);
        body && img.parentNode.removeChild(img);
    };
    // 圖片加載錯誤
    img.onerror = function () {
        error && error();
        clearInterval(intervalId);
        body && img.parentNode.removeChild(img);
    };
};

 

好了,請觀賞使人愉悅的 DEMO :http://www.planeart.cn/demo/imgReady/

(經過測試的瀏覽器:Chrome、Firefox、Safari、Opera、IE六、IE七、IE8)

經典論壇交流
http://bbs.blueidea.com/thread-3014603-1-1.html

本文連接:http://www.blueidea.com/tech/web/2011/8335.asp

相關文章
相關標籤/搜索