2010-03-15 18 views
21

Kurzfassung Frage: Gibt es navigator.mozIsLocallyAvailable gleichwertige Funktion, die auf allen Browsern funktioniert, oder eine Alternative?Post-loading: Überprüfen, ob ein Bild im Browser-Cache ist

Lange Version :)

Hallo, Hier ist meine Situation: ich eine Htmlhelper-Erweiterung für asp.net MVC implementieren möchten, die leicht Bild Nachladen Griff (mit jQuery).

Also rendere ich die Seite mit leeren Bildquellen mit der im Attribut "alt" angegebenen Quelle. Ich füge Bildquellen nach dem Ereignis "window.onload" ein und es funktioniert großartig.

ich so etwas wie dies tat:

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

Das Problem ist: Nach dem ersten Laden, nachgeladen Bilder werden im Cache gespeichert. Wenn die Seite jedoch 10 Sekunden zum Laden benötigt, werden die im Cache gespeicherten nachgeladenen Bilder nach diesen 10 Sekunden angezeigt.

Also ich denke, Bildquellen auf dem Ereignis "document.ready" anzugeben, wenn das Bild zwischengespeichert wird, um sie sofort anzuzeigen.

Ich habe diese Funktion gefunden: navigator.mozIsLocallyAvailable, um zu überprüfen, ob ein Bild im Cache ist. Hier ist, was ich mit jquery gemacht habe:

//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")); 
    }); 
}); 

Es funktioniert auf Mozilla DOM aber es funktioniert nicht auf jedem anderen. Ich habe versucht, navigator.isLocallyAvailable: das gleiche Ergebnis.

Gibt es eine Alternative?

Antwort

15

nach einigen reseach, fand ich eine Lösung:

Die Idee ist, die im Cache gespeicherten Bilder, Binden eine Log-Funktion auf den Bildern 'load' Ereignis zu protokollieren. Ich dachte zuerst, Quellen in einem Cookie zu speichern, aber es ist nicht zuverlässig, wenn der Cache ohne den Cookie gelöscht wird. Darüber hinaus fügt es ein weiteres Cookie auf HTTP-Anfragen ...

Dann traf ich die Magie: window.localStorage (details)

Das local Attribut stellt persistente Speicherbereiche für Domänen

Genau was ich wollte :). Dieses Attribut ist in HTML5 standardisiert und funktioniert bereits bei fast allen aktuellen Browsern (FF, Opera, Safari, IE8, Chrome).

Hier ist der Code (ohne window.localStorage nicht-kompatible Browser Handling):

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

Ich denke, das wird brechen, wenn Cache läuft ab ... Sie müssten das Ablaufdatum aus dem Response-Header (der einen Ajax-Aufruf erfordern würde) in localStorage speichern, zB "localStorage [src] = expires" in logCache und 'now Corin

+0

Auf den zweiten Gedanken ist dies wahrscheinlich kein großes Problem, da wir über Bilder sprechen ... – Corin

+0

Was passiert, wenn der Cache manuell gelöscht wird? – Parth

4

Eine Ajax-Anforderung für das Bild würde fast sofort zurückgegeben, wenn es zwischengespeichert wird. Verwenden Sie dann setTimeout, um festzustellen, ob es nicht bereit ist, und brechen Sie die Anfrage ab, damit Sie sie später erneut anfordern können.

Update:

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

Danke für Ihre intersting Antwort. Ich habe es getestet, aber es gibt ein Problem :( Der Erfolg Callback wird sofort ausgelöst, weit vor dem vollständigen Laden des Bildes. Ich habe versucht, das "Erfolg" -Ereignis durch "complete", das gleiche zu ersetzen denke, dass die Erfolg/Complete Ereignisse warten nicht das Laden der Komponenten der Antwort zu triggern. – Mathieu

+0

Wie auch immer das Problem ist, dass diese Lösung die HTTP-Anforderungsnummer zu verdoppeln. Ich möchte das vermeiden. – Mathieu

4

ich eine Bemerkung über Ihre leeren Bildquellen haben. Sie haben geschrieben:

So rendere ich die Seite mit leeren Bildquellen mit der Quelle in der "Alt" -Attribut angegeben. Ich füge Bildquellen nach dem Ereignis "window.onload" ein und es funktioniert großartig.

Ich habe in der Vergangenheit Probleme damit gehabt, weil in einigen Browsern leere src Attribute zusätzliche Anforderungen verursachen. Hier ist, was sie tun (kopiert von Yahoo! performance rules, gibt es auch eine blog post zu diesem Thema mit mehr Details):

  • Internet Explorer eine Anforderung an das Verzeichnis macht, in dem die Seite befindet.
  • Safari und Chrome stellen eine Anfrage an die eigentliche Seite selbst.
  • Firefox 3 und frühere Versionen verhalten sich genauso wie Safari und Chrome, aber Version 3.5 behebt dieses Problem [Bug 444931] und sendet keine Anfrage mehr.
  • Opera macht nichts, wenn ein leeres Bild src gefunden wird.

Wir verwenden auch viele jQuery auf unserer Website, und es war nicht immer möglich, leere Bild-Tags zu vermeiden. Ich habe gewählt, ein 1x1 px transparentes gif wie so zu verwenden: src="t.gif" für Bilder, die ich nur nach pageload einfüge. Es ist sehr klein und wird vom Browser zwischengespeichert. Das hat sehr gut für uns funktioniert.

Cheers, Oliver

+0

Hallo Oliver, du hast Recht. Eine andere Lösung, die ich verwendet habe, ist ein Span-Set mit der gleichen Breite und Höhe wie das Bild sein wird. Darüber hinaus haben HTML5 benutzerdefinierte Attribute, so dass sie verwendet werden: ersetzen Sie dann das Skript die gesamte Spanne von der Bild der benutzerdefinierten Attribute mit Informationen. Grüße, Mathieu – Mathieu

2

Für den Fall, andere können über die gleiche Frage kommen. Einige der hier angebotenen Lösungen (nämlich das Speichern der Cache-Informationen in einem lokalen Browser-Datenspeicher) könnten aus zwei Gründen brechen. Erstens, wenn der Cache des Bildes abläuft und zweitens wenn der Cache vom Benutzer gelöscht wird. Ein anderer Ansatz wäre, die Quelle des Bildes auf einen Platzhalter zu setzen. Dann ändern Sie die Quelle zum Bildpfad/Namen. Auf diese Weise muss der Browser seinen eigenen Cache überprüfen. Sollte mit den meisten Browsern unabhängig von ihrer API funktionieren.

0

Im Jahr 2017 kann Ihnen die API für das Ressourcen-Timing helfen, dies mithilfe der PerformanceResourceTiming.transferSize-Eigenschaft zu überprüfen. Diese Eigenschaft muss eine Nicht-Null-Übertragungsgröße zurückgeben, wenn sie vom Server heruntergeladen wird (nicht zwischengespeichert) und Null zurückgibt, wenn sie aus einem lokalen Cache abgerufen wird.

Referenz: https://developer.mozilla.org/en-US/docs/Web/API/PerformanceResourceTiming/transferSize

Verwandte Themen