javascript lazyload教學 - 後加載:檢查圖像是否在瀏覽器緩存中




jquery loading (6)

簡短版本問題:是否有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,但它不適用於任何其他DOM。 我試過navigator.isLocallyAvailable:相同的結果。

還有其他選擇嗎?


Answers

如果緩存,則幾乎立即返回對圖像的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;
}

經過一番研究,我找到了一個解決方案:

我們的想法是記錄緩存的圖像,在圖像的“加載”事件上綁定日誌功能。 我首先考慮將源存儲在cookie中,但如果在沒有cookie的情況下清除緩存則不可靠。 此外,它還為HTTP請求添加了一個cookie ...

然後我遇到了魔法: 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"));
    });
});

以防萬一其他人可能遇到同樣的問題。 這裡提供的一些解決方案(即將緩存信息存儲在本地瀏覽器數據存儲中)可能會因為兩個原因而中斷。 首先,如果圖像的高速緩存到期,則第二,如果用戶清除了高速緩存。 另一種方法是將圖像源設置為佔位符。 然後將源更改為圖像路徑/名稱。 這樣,瀏覽器就有責任檢查自己的緩存。 適用於大多數瀏覽器,無論其API如何。


我對你的空圖像來源有一個評論。 你寫了:

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

我在過去遇到過這個問題,因為在某些瀏覽器中,空src屬性會導致額外的請求。 這是他們的行為(從Yahoo!性能規則中復制,還有關於該問題的博客文章 ,更詳細):

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

我們在網站上也使用了很多jQuery,並不總是可以避免空圖像標記。 我選擇使用像這樣的1x1 px透明gif: src="t.gif"用於我僅在src="t.gif"之後插入的圖像。 它非常小,可以通過瀏覽器進行緩存。 這對我們來說非常有效。

乾杯,奧利弗


檢查圖像是否已被緩存的最有效,最簡單且廣泛支持的方法是執行以下操作...

  1. 創建一個圖像對象
  2. 將src屬性設置為所需的URL
  3. 立即檢查已完成的屬性以查看圖像是否已緩存
  4. 將src屬性設置回“”或空白,以便不會不必要地加載圖像

像這樣......

function is_cached(src) {
    var img = new Image();
    img.src = src;
    var complete = img.complete;
    img.src = "";
    return complete;
}

我用這個:

 <input type="checkbox" id="isAgeSelected" value="1" /> <br/>
 <input type="textbox" id="txtAge" />

 $("#isAgeSelected").is(':checked') ? $("#txtAge").show() : $("#txtAge").hide();




javascript jquery caching lazy-loading