圖片預加載

模仿【http://www.otomate.jp/ghp/fd/】的圖片預加載所寫。該頁使用jQuery,這裏使用原生javascript。javascript

在ie6,ie8,FF,Chrome,Opera下測試經過。css

 

過程:java

一、在DOM樹加載完畢時,將頁面內全部圖片(img標籤,css中的背景圖)的地址push進一個數組。web

二、用image圖片加載完成觸發的load事件進行回調,顯示當前進度。【已加載完圖片數/總圖片數】正則表達式

三、圖片所有加載完畢,進行以後的處理。(如上述url頁所示,將遮罩層移除)編程

 

關鍵點:數組

javascript一般採用非阻塞式(異步)編程,故而沒法順次加載圖片。瀏覽器

所以必須在每張圖片加載完後觸發一個回調函數,在回調函數中判斷是否所有加載完畢。緩存

 

相關代碼步驟:異步

一、DOM樹加載完畢的事件(jQuery的docuiment ready)

window.onload會在全部資源加載完畢後觸發,故而不能使用。

大部分現代瀏覽器支持DOMContentLoaded事件【webkit525版本如下(safari 3.1如下)不支持,這裏不做考慮】;

IE支持readystatechange事件,監聽document.readyState屬性爲【interactive】或【complete】時便可認爲加載完畢。

相關代碼以下,以《JS高級程序設計》爲參考,並做了處理防止重複判斷是IE仍是現代瀏覽器。

 1 CCC.documentReady = function(f){
 2     if( document.addEventListener ) {
 3         CCC.documentReady = function(func){
 4             document.addEventListener('DOMContentLoaded', function(){
 5                 document.removeEventListener('DOMContentLoaded', arguments.callee);
 6                 func();
 7             }, false); 
 8         };
 9     } else {
10         CCC.documentReady = function(func){
11             document.attachEvent('onreadystatechange', function(){
12                 if (document.readyState == 'interactive' || document.readyState == 'complete') {
13                     document.detachEvent('onreadystatechange', arguments.callee);
14                     func();
15                 }
16             }); 
17         };
18     }
19     CCC.documentReady(f);
20 };
View Code

二、獲取圖片url

getStyle爲一個獲取計算後樣式的方法,作了兼容。

各瀏覽器獲取到的background-image屬性,格式爲【url(...)】,可能包含雙引號【url("...")】,所以正則表達式須要考慮到這些狀況。

bg.replace(/url\("?([^"]+)"?\)/, '$1');

var all = document.body.getElementsByTagName('*');
var imgUrls = [];
for(var i = 0, len = all.length; i < len; i++) {
    if(all[i].tagName.toLowerCase() == 'img') {
        if(all[i].src) {
            imgUrls.push(all[i].src);
        } 
    } else {
        var bg = _(all[i]).getStyle('background-image');
        if(/url/.test(bg)) {
            bg = bg.replace(/url\("?([^"]+)"?\)/, '$1');
            imgUrls.push(bg);
        }
    }
}
View Code

三、preload預加載函數

經過對Image對象設置src屬性來加載圖片。

如在瀏覽器中已有緩存,則直接回調;不然添加onload事件處理函數,異步回調。

complete爲當前已加載完畢的圖片數。

function preload(arr, callback){
    var complete = 0;
    for(var i = 0, len = arr.length; i < len; i++) {
        var img = new Image();
        img.src = arr[i];;
        if(img.complete) { /* 已緩存 */
            callback(++complete, len);
            continue;
        }
        img.onload = function(){
            callback(++complete, len);
        };
    }
}
View Code

四、使用preload函數

在回調方法中,使用一個input標籤顯示當前進度;

當所有加載完畢(經過complete >= len來判斷),進行最後的處理。這裏僅僅是簡單的alert。

preload(imgUrls, function(complete, len){
    if(complete >= len) {
        progress.value = '100%';
        imgUrls = null;
        alert('complete');
        return;
    }
    progress.value = parseInt(complete * 100 / len) + '%';
});
View Code

以上簡陋代碼僅做我的思路記錄,

相關文章
相關標籤/搜索