模仿【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 };
二、獲取圖片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); } } }
三、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); }; } }
四、使用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) + '%'; });
以上簡陋代碼僅做我的思路記錄,