(先制攻撃:これを重複としてマークしたい場合は、「なぜこのエラーが発生するのですか?このエラーが発生しましたJavaScriptコードのエラーをどのように検出できるのかを知りたいのですが、Firebugコンソールにしか表示されず、画像がロードされたときにユーザーには明らかです)Firefoxで「画像が壊れているか切り詰められていますか」を検出します
I応答性の高い画像にはpicturefillを使用しています。私は画像上のloadイベントのために起動されるコールバックを持っています。したがって、誰かがブラウザウィンドウのサイズを変更するたびにコールバックが実行され、異なる画像がpicturefillによって読み込まれるようになります。
コールバックの中で、イメージデータをキャンバス経由でdataURLに変換しています。ローカルデータをlocalStorageにキャッシュして、オフラインでも利用できるようにします。
「オフライン」に関する部分に注意してください。そのため、私はブラウザのキャッシュに頼ることができません。イメージが応答性があるため、HTML5オフラインアプリケーションキャッシュが私のニーズを満たしていません。
MacのFirefox 14.0.1では、ブラウザのサイズを本当に大きかったサイズに変更してからサイズを変更すると、読み込みイメージが表示されます(これは、応答イメージとHTMLオフラインアプリケーションキャッシュとの非互換性の説明を参照してください)。大きなイメージが完全に読み込まれる前にもう一度小さなものに戻ってください。 Firebugコンソールで "Image corrupt or truncated"と報告されますが、例外はスローされず、エラーイベントも発生しません。コードに何も間違っていることは示されません。 Firebugコンソールで一方、切り捨てられたイメージはlocalStorageに格納されます。
JavaScriptでこの問題を確実かつ効率的に検出して、その画像をキャッシュしないようにするにはどうすればよいですか?
はここpicturefillによって挿入されているのimgタグを見つける方法Iループpicturefillのdivを経由だ:ここ
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];
}
};
最後に、:
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);
}
}
}
}
}
そして、ここではcacheImage()
コールバックは次のようになります。私がFirebugで見ているURLのフルテキストです。
破損または切り捨て
'
'要素で 'error'イベントが発生しませんか? –
MaxArt
なぜ、ブラウザのキャッシュに自分の仕事をさせるのではなく、自分のイメージキャッシュをローカルストレージに実装しようとしているのだろうか? – jfriend00
@ jfriend00オフラインで使用するためにイメージをキャッシュします。私はこの質問に答えましたが、私はそれを脇見のように表現しました。私はオフラインビットにもっと重点を置くように質問を編集しました。とにかく、次に明らかになるのは、HTML5のオフラインappcachingを使用しない理由です。応答イメージとHTML5オフラインアプリケーションキャッシングが互換性がない理由については、http://www.alistapart.com/articles/application-cache-is-a-douchebag/ – Trott