(Golpe preventivo: si tiene la tentación de marcar esto como un duplicado, tenga en cuenta que otras preguntas parecen preguntar "¿por qué me sale este error?" Sé por qué Estoy obteniendo este error, quiero saber cómo puedo detectar el error en mi código JavaScript. Aparece solo en la consola Firebug y, por supuesto, es obvio para el usuario cuando se carga la imagen.)Detectar "imagen dañada o truncada" en Firefox
I Estoy usando picturefill para imágenes receptivas. Tengo una devolución de llamada que se activa para el evento de carga en las imágenes. Por lo tanto, la devolución de llamada se ejecuta cada vez que alguien cambia el tamaño de la ventana del navegador de forma que se cargue una imagen diferente a través del relleno de imagen.
Dentro de la devolución de llamada, estoy convirtiendo los datos de imagen a través de un DataURL tela para que pueda almacenar en caché los datos de imagen en localStorage por lo que su disponibles para el usuario incluso cuando están fuera de línea.
Tenga en cuenta la parte sobre "fuera de línea". Es por eso que no puedo confiar en el caché del navegador. Y el caché de aplicaciones sin conexión de HTML5 no satisface mis necesidades porque las imágenes son receptivas. (Consulte "Application Cache is a Douchebag" para la explicación de la incompatibilidad de imágenes receptivas con la caché de aplicaciones sin conexión HTML.)
En Firefox 14.0.1 en una Mac, la imagen de carga se activará si cambio el tamaño del navegador a algo realmente grande y luego lo cambio de tamaño vuelve a bajar a algo pequeño antes de que la imagen grande tenga la oportunidad de cargarse por completo. Termina informando "Imagen dañada o truncada" en la consola de Firebug, pero no arroja una excepción ni desencadena un evento de error. No hay indicación de que algo esté mal en el código. Solo en la consola Firebug. Mientras tanto, almacena una imagen truncada en localStorage.
¿Cómo puedo detectar de manera confiable y eficiente este problema dentro de JavaScript para que no guarde en caché esa imagen?
Así es como me bucle a través de los divs picturefill para encontrar las etiquetas img que han sido insertados por picturefill:
var errorLogger = function() {
window.console.log('Error loading image.');
this.removeEventListener('load', cacheImage, false);
};
for(var i = 0, il = ps.length; i < il; i++){
if(ps[ i ].getAttribute("data-picture") !== null){
image = ps[ i ].getElementsByTagName("img")[0];
if (image) {
if ((imageSrc = image.getAttribute("src")) !== null) {
if (imageSrc.substr(0,5) !== "data:") {
image.addEventListener("load", cacheImage, false);
image.addEventListener('error', errorLogger, false);
}
}
}
}
}
Y aquí es lo que el cacheImage()
devolución de llamada se parece a:
var cacheImage = function() {
var canvas,
ctx,
imageSrc;
imageSrc = this.getAttribute("src");
if ((pf_index.hasOwnProperty('pf_s_' + imageSrc)) ||
(imageSrc.substr(0,5) === "data:") ||
(imageSrc === null) || (imageSrc.length === 0)) {
return;
}
canvas = w.document.createElement("canvas");
canvas.width = this.width;
canvas.height = this.height;
ctx = canvas.getContext("2d");
ctx.drawImage(this, 0, 0);
try {
dataUri = canvas.toDataURL();
} catch (e) {
// TODO: Improve error handling here. For now, if canvas.toDataURL()
// throws an exception, don't cache the image and move on.
return;
}
// Do not cache if the resulting cache item will take more than 128Kb.
if (dataUri.length > 131072) {
return;
}
pf_index["pf_s_"+imageSrc] = 1;
try {
localStorage.setItem("pf_s_"+imageSrc, dataUri);
localStorage.setItem("pf_index", JSON.stringify(pf_index));
} catch (e) {
// Caching failed. Remove item from index object so next cached item
// doesn't wrongly indicate this item was successfully cached.
delete pf_index["pf_s_"+imageSrc];
}
};
Por último, aquí es el texto completo de lo que estoy viendo en Firebug con la URL modificada para proteger a los culpables:
de imagen dañado o truncado: http://www.example.com/pf/external/imgs/extralarge.png
¿No desencadena un evento 'error' en el elemento' '? – MaxArt
¿Uno podría preguntarse por qué está tratando de implementar su propio almacenamiento en caché de imágenes en el almacenamiento local en lugar de dejar que el caché del navegador lo haga funcionar? – jfriend00
@ jfriend00 Estoy almacenando en caché la imagen para uso fuera de línea. Dije esto en la pregunta, pero lo expresé como un aparte. He editado la pregunta para darle más énfasis al bit fuera de línea. De todos modos, la siguiente pregunta obvia es por qué no utilizar la aplicación de aplicaciones HTML5 sin conexión. Para obtener una explicación sobre por qué las imágenes receptivas y la aplicación de aplicaciones fuera de línea de HTML5 son incompatibles, consulte http://www.alistapart.com/articles/application-cache-is-a-douchebag/ – Trott