(先发制人:如果您想将此标记为重复,请注意其他问题似乎在问“我为什么会收到此错误?”我知道为什么我会收到此错误;我想要知道如何在我的JavaScript代码中检测到错误。它只出现在Firebug控制台中,当然,在加载图像时对用户来说是显而易见的。)
我正在使用picturefill来回复图片。我有一个针对图像上的load事件触发的回调。因此,每当有人调整浏览器窗口大小以便通过picturefill加载不同的图像时,回调就会运行。
在回调中,我正在通过画布将图像数据转换为dataURL,这样我就可以将图像数据缓存在localStorage中,这样即使用户离线也可以使用它。
请注意有关“离线”的部分。这就是我不能依赖浏览器缓存的原因。 HTML5离线应用程序缓存无法满足我的需求,因为图像是响应式的。 (有关响应式图像与HTML脱机应用程序缓存不兼容的说明,请参阅"Application Cache is a Douchebag"。)
在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];
}
};
最后,这里是我在Firebug中看到的全文,其URL已更改以保护有罪:
图片损坏或截断:http://www.example.com/pf/external/imgs/extralarge.png
答案 0 :(得分:9)
在更改src
标记的img
属性时,Firefox似乎会触发load
事件。这与HTML5规范相反,says如果更改了src属性,那么任何其他正在进行的提取都应该结束(Firefox会这样做),并且不应该发送任何事件。仅当获取成功完成时才应发送load
事件。所以我要说你得到load
事件的事实是Firefox的错误。
但是,图片应知道它是否完全可用,您可以尝试使用complete
属性:
if (this.complete === false) {
return;
}
不幸的是,Firefox已将this.complete
设置为true
,因此这也不是一个选项。
最佳选择可能是每次要更改<img>
属性时创建新的src
元素。
答案 1 :(得分:2)
我今天对这个问题感到茫然。一切都运行良好(图像按预期加载)除了错误一直出现在Firefox错误控制台中 - 但IE或Chrome中没有这样的错误。
在我的情况下,我在一个完整的jquery处理程序中使用innerHtml将图像插入到div中。当我用:#/ p>抢占jquery调用时,错误停止了
var image_holder = new Image();
image_holder.src = img_path;//path of image that's going to be plugged in
它对我有用,但它仍然没有意义。我认为它与时序有关,因为这段代码在它到达实际将其插入页面的代码之前启动图像加载。