(Attacco preventivo: se si è tentati di contrassegnarlo come duplicato, si noti che altre domande sembrano chiedere "perché ottengo questo errore?". So perché sto ottenendo questo errore, voglio sapere come posso rilevare l'errore nel mio codice JavaScript, appare solo nella console Firebug e, ovviamente, è ovvio all'utente quando l'immagine viene caricata.)Rileva "immagine corrotta o troncata" in Firefox
I Sto usando picturefill per le immagini reattive. Ho un callback che viene attivato per l'evento load sulle immagini. Quindi la richiamata viene eseguita ogni volta che qualcuno ridimensiona la finestra del browser in modo tale che un'immagine diversa venga caricata tramite picturefill.
All'interno del callback, sto convertendo i dati dell'immagine in un dataURL tramite canvas in modo da poter memorizzare nella cache i dati dell'immagine in localStorage in modo che siano disponibili all'utente anche quando sono offline.
Nota la parte relativa a "non in linea". Ecco perché non posso fare affidamento sulla cache del browser. E la cache dell'applicazione offline HTML5 non soddisfa le mie esigenze perché le immagini sono reattive. (Vedere "Application Cache is a Douchebag" per la spiegazione dell'incompatibilità delle immagini reattive con cache di applicazioni offline HTML.)
Su Firefox 14.0.1 su un Mac, l'immagine di caricamento viene attivata se ridimensiono il browser a qualcosa di veramente grande e poi lo ridimensiono torna di nuovo a qualcosa di piccolo prima che l'immagine grande abbia la possibilità di caricarsi completamente. Finisce per segnalare "Immagine danneggiata o troncata" nella console di Firebug, ma non lancia un'eccezione o attiva un evento di errore. Nessuna indicazione c'è qualcosa di sbagliato nel codice. Solo nella console di Firebug. Nel frattempo, memorizza un'immagine troncata in localStorage.
Come posso rilevare in modo affidabile ed efficiente questo problema all'interno di JavaScript in modo da non memorizzare nella cache quell'immagine?
Ecco come lo scorrere il div picturefill per trovare i tag img che sono stati inseriti da 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);
}
}
}
}
}
Ed ecco quello che la richiamata cacheImage()
assomiglia:
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];
}
};
Infine, qui è il testo completo di ciò che sto vedendo in Firebug con l'URL modificato per proteggere il colpevole:
Immagine corrotto o troncato: http://www.example.com/pf/external/imgs/extralarge.png
Non attiva un evento 'error' sull'elemento' '? – MaxArt
Ci si potrebbe chiedere perché stai cercando di implementare la memorizzazione nella cache delle immagini nella memoria locale invece di lasciare che la cache del browser faccia funzionare? – jfriend00
@ jfriend00 Sto memorizzando l'immagine nella cache per l'utilizzo offline. L'ho detto nella domanda, ma l'ho espresso come un accenno. Ho modificato la domanda per dare maggiore enfasi al bit offline. Ad ogni modo, la prossima domanda ovvia è perché non utilizzare applaching offline HTML5. Per la spiegazione del motivo per cui le immagini reattive e la applaching offline HTML5 non sono compatibili, consultare http://www.alistapart.com/articles/application-cache-is-a-douchebag/ – Trott