2010-03-15 46 views
21

短版問題: 有沒有在所有瀏覽器,或替代工作navigator.mozIsLocallyAvailable同等功能?後負荷:檢查如果圖像是在瀏覽器緩存

龍版:)

嗨, 這裏是我的情況: 我要實現對asp.net MVC的的HtmlHelper擴展,輕鬆處理圖像後加載(使用jQuery)。

因此,我使用「alt」屬性中指定的源渲染帶有空圖像源的頁面。 我在「window.onload」事件之後插入圖像源,並且效果很好。

我做了這樣的事情:

$(window).bind('load', function() { 
    var plImages = $(".postLoad"); 
    plImages.each(function() { 
     $(this).attr("src", $(this).attr("alt")); 
    }); 
}); 

的問題是:第一裝載後,後加載的圖像緩存。但是,如果頁面需要10秒鐘才能加載,則在此10秒後將顯示緩存的已加載後的圖像。

所以我認爲如果圖像被緩存以立即顯示它們,則在「document.ready」事件中指定圖像源。

我發現這個函數:navigator.mozIsLocallyAvailable來檢查圖像是否在緩存中。下面是我用jQuery做:

//specify cached image sources on dom ready 
$(document).ready(function() { 
    var plImages = $(".postLoad"); 
    plImages.each(function() { 
     var source = $(this).attr("alt") 
     var disponible = navigator.mozIsLocallyAvailable(source, true); 
     if (disponible) 
      $(this).attr("src", source); 
    }); 
}); 

//specify uncached image sources after page loading 
$(window).bind('load', function() { 
     var plImages = $(".postLoad"); 
     plImages.each(function() { 
     if ($(this).attr("src") == "") 
      $(this).attr("src", $(this).attr("alt")); 
    }); 
}); 

它適用於Mozilla的DOM,但它並不適用於其他任何一個。我嘗試了navigator.isLocallyAvailable:結果相同。

有沒有其他的選擇?

回答

15

一些研製後,我發現了一個解決方案:

的想法是記錄在緩存圖像,結合圖像上「加載」事件日誌功能。 我首先想到了將源代碼存儲在一個cookie中,但如果緩存沒有被cookie清除,它就不可靠。此外,它增加了一個更多的cookie HTTP請求......

後來我遇到了神奇的:window.localStoragedetails

的localStorage的屬性爲域 持久存儲區

正是我想要的:)。該屬性在HTML5中進行了標準化,並且幾乎適用於所有最新的瀏覽器(FF,Opera,Safari,IE8,Chrome)。

下面是代碼(不處理window.localStorage不兼容的瀏覽器):

var storage = window.localStorage; 
if (!storage.cachedElements) { 
    storage.cachedElements = ""; 
} 

function logCache(source) { 
    if (storage.cachedElements.indexOf(source, 0) < 0) { 
     if (storage.cachedElements != "") 
      storage.cachedElements += ";"; 
     storage.cachedElements += source; 
    } 
} 

function cached(source) { 
    return (storage.cachedElements.indexOf(source, 0) >= 0); 
} 

var plImages; 

//On DOM Ready 
$(document).ready(function() { 
    plImages = $(".postLoad"); 

    //log cached images 
    plImages.bind('load', function() { 
     logCache($(this).attr("src")); 
    }); 

    //display cached images 
    plImages.each(function() { 
     var source = $(this).attr("alt") 
     if (cached(source)) 
      $(this).attr("src", source); 
    }); 
}); 

//After page loading 
$(window).bind('load', function() { 
    //display uncached images 
    plImages.each(function() { 
     if ($(this).attr("src") == "") 
      $(this).attr("src", $(this).attr("alt")); 
    }); 
}); 
+8

我認爲這將打破時緩存過期...您需要在localStorage中存儲響應頭文件(需要ajax調用)的過期日期,例如,在logCache中使用'localStorage [src] = expires'並在緩存中使用'now Corin 2011-07-03 05:58:11

+0

第二個想法可能不是一個大問題,因爲我們正在討論圖像...... – Corin 2011-07-03 05:58:57

+0

如果手動清除緩存會發生什麼? – Parth 2016-03-20 08:40:58

4

如果緩存了圖像的ajax請求,它幾乎會立即返回。然後使用setTimeout來確定它是否沒有準備好並取消請求,以便稍後重新請求它。

更新:

var lqueue = []; 
$(function() { 
    var t,ac=0; 
    (t = $("img")).each(
    function(i,e) 
    { 
     var rq = $.ajax(
     { 
     cache: true, 
     type: "GET", 
     async:true, 
     url:e.alt, 
     success: function() { var rq3=rq; if (rq3.readyState==4) { e.src=e.alt; } }, 
     error: function() { e.src=e.alt; } 
     }); 

     setTimeout(function() 
     { 
     var k=i,e2=e,r2=rq; 
     if (r2.readyState != 4) 
     { 
      r2.abort(); 
      lqueue.push(e2); 
     } 
     if (t.length==(++ac)) loadRequeue(); 
     }, 0); 
    } 
); 
}); 

function loadRequeue() 
{ 
    for(var j = 0; j < lqueue.length; j++) lqueue[j].src=lqueue[j].alt; 
} 
+0

感謝您的intersting答案。我已經測試過,但有一個問題:( 成功回調立即觸發,遠在完成加載圖像之前 我試圖用「完成」來替換「成功」事件,同樣的事情。認爲成功/完成事件不會等待加載組件的響應觸發 – Mathieu 2010-03-16 00:34:31

+0

無論如何,問題是這個解決方案加倍HTTP請求號碼,我想避免這種情況 – Mathieu 2010-03-16 20:14:23

4

我有一個關於你的空圖像源的話。你寫道:

因此,我使用「alt」屬性中指定的源渲染帶有空圖像源的頁面。我在「window.onload」事件後插入圖像源,並且效果很好。

我以前遇到過這個問題,因爲在某些瀏覽器中,空src屬性會導致額外的請求。這裏是他們做了什麼(從Yahoo! performance rules複製,這裏還有關於該問題的一個blog post更多的細節):

  • 通過Internet Explorer可以在該頁面所在的目錄的請求。
  • Safari和Chrome向實際頁面本身發出請求。
  • Firefox 3及更早版本的行爲與Safari和Chrome相同,但版本3.5解決了此問題[錯誤444931],不再發送請求。
  • 當遇到空的圖像src時,Opera不會執行任何操作。

我們還在我們的網站上使用了很多jQuery,而且它並不總是可以避免空圖像標籤。我選擇了像這樣使用1x1像素透明gif:src="t.gif"用於僅在頁面加載後插入的圖像。它非常小,並被瀏覽器緩存。這對我們來說非常有效。

乾杯,奧利弗

+0

嗨,奧利弗你說得對。我使用的另一個解決方案是設置與圖像寬度和高度相同的跨度。此外,HTML5具有如下定製屬性: 然後,腳本替換使用自定義圖像整個跨度屬性信息。 問候,Mathieu – Mathieu 2010-08-02 07:50:08

2

萬一別人可能會遇到同樣的問題。這裏提供的一些解決方案(即將緩存信息存儲在本地瀏覽器數據存儲中)可能會因爲兩個原因而中斷。首先,如果圖像的緩存過期,其次如果緩存被用戶清除。另一種方法是將圖像源設置爲佔位符。然後將源代碼更改爲圖像路徑/名稱。這樣,瀏覽器就有責任檢查自己的緩存。應該適用於大多數瀏覽器,而不管他們的API。