(先制攻撃: これを重複としてマークしたい場合は、他の質問が「なぜこのエラーが発生するのか?」と尋ねているように見えることに注意してください。私はこのエラーが発生する理由を知っています。 JavaScript コードのエラーを検出できます. Firebug コンソールにのみ表示され、もちろん、画像がロードされたときにユーザーには明らかです.)
レスポンシブ画像にピクチャーフィルを使用しています。画像の読み込みイベントに対して発生するコールバックがあります。したがって、コールバックは、別の画像が picturefill によって読み込まれるように、誰かがブラウザ ウィンドウのサイズを変更するたびに実行されます。
コールバック内で、canvas を介して画像データを dataURL に変換し、画像データを localStorage にキャッシュして、ユーザーがオフラインの場合でも使用できるようにします。
「オフライン」に関する部分に注意してください。そのため、ブラウザのキャッシュに頼ることはできません。また、画像がレスポンシブであるため、HTML5 オフライン アプリケーション キャッシュは私のニーズを満たしていません。(レスポンシブ画像と HTML オフライン アプリケーション キャッシュとの非互換性については、「アプリケーション キャッシュはおせっかい」を参照してください。)
Mac 上の Firefox 14.0.1 では、大きな画像が完全に読み込まれる前に、ブラウザーを非常に大きなサイズに変更し、再度小さなサイズに戻すと、読み込み画像が起動します。最終的に、Firebug コンソールで「画像が破損しているか切り捨てられています」と報告されますが、例外はスローされず、エラー イベントもトリガーされません。コードに何か問題があることを示すものはありません。ちょうど Firebug コンソールで。その間、切り捨てられたイメージを localStorage に格納します。
その画像をキャッシュしないように、JavaScript 内でこの問題を確実かつ効率的に検出するにはどうすればよいですか?
これは、picturefill div をループして、picturefill によって挿入された img タグを見つける方法です。
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()
ます。
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];
}
};
最後に、有罪を保護するために URL が変更された、Firebug で表示されているものの全文を次に示します。
画像の破損または切り捨て: http://www.example.com/pf/external/imgs/extralarge.png