2010-03-15 7 views
21

Pregunta corta pregunta: ¿Hay función equivalente navigator.mozIsLocallyAvailable que funcione en todos los navegadores, o una alternativa?Post-carga: verifique si hay una imagen en el caché del navegador

Versión larga :)

Hola, Aquí está mi situación: Quiero poner en práctica una extensión HtmlHelper para asp.net MVC que se encargan de la imagen después de la carga con facilidad (con jQuery).

Por lo tanto, renderizo la página con fuentes de imagen vacías con la fuente especificada en el atributo "alt". Inserto fuentes de imagen después del evento "window.onload" y funciona muy bien.

he hecho algo como esto:

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

El problema es: Después de la primera carga, imágenes post cargado se almacenan en caché. Pero si la página tarda 10 segundos en cargarse, las imágenes cargadas en la memoria caché se mostrarán después de estos 10 segundos.

Creo que para especificar las fuentes de imagen en el evento "document.ready" si la imagen se almacena en caché para mostrarlas de inmediato.

Encontré esta función: navigator.mozIsLocallyAvailable para verificar si una imagen está en la caché. Esto es lo que he hecho con 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")); 
    }); 
}); 

Funciona en DOM de Mozilla, pero no funciona en cualquier otro. Intenté navigator.isLocallyAvailable: mismo resultado.

¿Hay alguna alternativa?

Respuesta

15

después de algún reseach, he encontrado una solución:

La idea es iniciar sesión en caché las imágenes, la unión de una función de registro en las imágenes de 'carga' evento. Primero pensé en almacenar fuentes en una cookie, pero no es confiable si la memoria caché se borra sin la cookie. Además, se añade una galleta más a las peticiones HTTP ...

Entonces me encontré con la magia: window.localStorage (details)

El atributo localStorage ofrece áreas de almacenamiento persistente para los dominios

Exactamente lo que quería :). Este atributo está estandarizado en HTML5, y ya funciona en casi todos los navegadores recientes (FF, Opera, Safari, IE8, Chrome).

Aquí está el código (sin gastos de envío window.localStorage navegadores no compatibles):

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

Creo que esto se romperá cuando el caché caduca ... necesitaría almacenar la fecha de caducidad del encabezado de respuesta (que requeriría una llamada ajax) en localStorage. Por ejemplo 'localStorage [src] = expires' en logCache y' now Corin

+0

Pensándolo bien, esto probablemente no sea un gran problema ya que estamos hablando de imágenes ... – Corin

+0

¿Qué sucede si la memoria caché se borra manualmente? – Parth

4

Una solicitud ajax para la imagen volverá casi de inmediato si está en caché. Luego use setTimeout para determinar si no está listo y cancele la solicitud para que pueda volver a ponerla en la cola para más adelante.

Actualización:

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

Gracias por su respuesta intersting. Lo he probado, pero hay un problema :( La devolución de llamada de éxito se desencadena inmediatamente, mucho antes de la carga completa de la imagen. Traté de reemplazar el evento "éxito" por "completo", lo mismo. Creo que los eventos de éxito/completo no están esperando la carga de los componentes de la respuesta para disparar – Mathieu

+0

De todos modos, el problema es que esta solución duplica el número de solicitud HTTP. Me gustaría evitar eso. – Mathieu

4

tengo una observación acerca de sus fuentes de imágenes vacías. Usted escribió:

Así que renderizo la página con fuentes de imagen vacías con la fuente especificada en el atributo "alt". Inserto las fuentes de imagen después del evento "window.onload" y funciona muy bien.

He tenido problemas con esto en el pasado, porque en algunos navegadores, los atributos src vacíos provocan solicitudes adicionales. Esto es lo que hacen (copiados de Yahoo! performance rules, también hay una blog post sobre esta cuestión con más detalle):

  • Internet Explorer realiza una solicitud al directorio en el que se encuentra la página.
  • Safari y Chrome hacen una solicitud a la página real.
  • Firefox 3 y versiones anteriores se comportan igual que Safari y Chrome, pero la versión 3.5 resolvió este problema [error 444931] y ya no envía una solicitud.
  • Opera no hace nada cuando se encuentra un src de imagen vacío.

También utilizamos una gran cantidad de jQuery en nuestro sitio, y no siempre ha sido posible evitar las etiquetas de imagen vacías. Elegí usar un gif transparente de 1x1 px como el siguiente: src="t.gif" para las imágenes que solo inserté después de la carga de la página. Es muy pequeño y el navegador lo almacena en caché. Esto ha funcionado muy bien para nosotros.

Cheers, Oliver

+0

Hola Oliver, tienes razón al respecto. Otra solución que utilicé es un span con el mismo ancho y alto que la imagen. Además, HTML5 tiene atributos personalizados para usarlo: A continuación, la secuencia de comandos en lugar de todo el arco de la imagen usando la información de atributos personalizados. Saludos, Mathieu – Mathieu

2

Sólo en caso de que otros pueden venir a través de la misma cuestión. algunas de las soluciones proporcionadas aquí (es decir, almacenar la información de la caché en un almacenamiento de datos del navegador local) podrían fallar por dos razones. En primer lugar, si el caché de la imagen caduca y, en segundo lugar, si el caché lo borra. Otro enfoque sería establecer la fuente de la imagen en un marcador de posición. Luego cambiando la fuente a la ruta/nombre de la imagen. De esta forma, será responsabilidad del navegador verificar su propio caché. Debería funcionar con la mayoría de los navegadores independientemente de su API.

Cuestiones relacionadas