2010-03-15 113 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。