我使用JavaScript和jQuery库来操作包含在无序列表中的图像缩略图。当图像加载时,它做一件事,当错误发生时,它做另一件事。我使用jQuery load()和error()方法作为事件。在这些事件之后,我检查图像DOM元素中的.complete,以确保在jQuery注册这些事件之前图像还没有加载。
它可以正常工作,除非在jQuery注册事件之前发生错误。我能想到的唯一解决方案是使用img onerror属性存储一个“标志”全局(或在节点本身),表示它失败了,这样jQuery就可以在检查.complete时检查“store/node”。
有人有更好的解决办法吗?
编辑:粗体的要点和添加额外的细节如下:
我正在检查图像是否完整(又名加载)后,我添加了一个加载和错误事件的图像。这样,如果图像是在事件注册之前加载的,我仍然会知道。如果图像在事件之后没有加载,那么当它加载时,事件会处理它。这样做的问题是,我可以很容易地检查图像是否已经加载,但我不能告诉是否发生了错误。
这是我如何让它跨浏览器使用上述方法的组合(我还需要动态插入图像到dom):
$('#domTarget').html('<img src="" />');
var url = '/some/image/path.png';
$('#domTarget img').load(function(){}).attr('src', url).error(function() {
if ( isIE ) {
var thisImg = this;
setTimeout(function() {
if ( ! thisImg.complete ) {
$(thisImg).attr('src', '/web/css/img/picture-broken-url.png');
}
},250);
} else {
$(this).attr('src', '/web/css/img/picture-broken-url.png');
}
});
注意:您需要为isIE变量提供一个有效的布尔状态。
在阅读了本页上有趣的解决方案后,我创建了一个易于使用的解决方案,深受SLaks和Noyo的帖子的影响,似乎在Chrome、IE、Firefox、Safari和Opera(都在Windows上)的最新版本上都可以使用。此外,它还可以在我使用的iPhone/iPad模拟器上运行。
这个解决方案与SLaks和Noyo的帖子之间的一个主要区别是,这个解决方案主要检查naturalWidth和naturalHeight属性。我发现在当前的浏览器版本中,这两个属性似乎提供了最有帮助和最一致的结果。
这段代码在图像完全加载成功时返回TRUE。当图像尚未完全加载或加载失败时,它返回FALSE。
你需要注意的一件事是,如果图像是0x0像素的图像,这个函数也会返回FALSE。但这些图像是相当不常见的,我想不出一个非常有用的情况下,你会想要检查一个0x0像素的图像是否已经加载:)
首先,我们将一个名为“isLoaded”的新函数附加到HTMLImageElement原型,以便该函数可以用于任何图像元素。
HTMLImageElement.prototype.isLoaded = function() {
// See if "naturalWidth" and "naturalHeight" properties are available.
if (typeof this.naturalWidth == 'number' && typeof this.naturalHeight == 'number')
return !(this.naturalWidth == 0 && this.naturalHeight == 0);
// See if "complete" property is available.
else if (typeof this.complete == 'boolean')
return this.complete;
// Fallback behavior: return TRUE.
else
return true;
};
然后,任何时候我们需要检查图像的加载状态,我们只需调用“isLoaded”函数。
if (someImgElement.isLoaded()) {
// YAY! The image loaded
}
else {
// Image has not loaded yet
}
根据giorgian在SLaks和Noyo的帖子上的评论,如果你打算改变SRC属性,这个解决方案可能只能用于Safari Mobile上的一次性检查。但是您可以通过创建一个带有新的SRC属性的图像元素来解决这个问题,而不是在现有的图像元素上更改SRC属性。
基于我对img元素的W3C HTML规范的理解,你应该能够使用complete和naturalHeight属性的组合来做到这一点,就像这样:
function imgLoaded(imgElement) {
return imgElement.complete && imgElement.naturalHeight !== 0;
}
complete属性的规范:
IDL属性complete如果出现下列情况之一,则必须返回true
条件为真:
src属性省略。
获取资源后由网络任务源排队的最后一个任务已经排队。
img元素是完全可用的。
img元素被破坏了。
否则,该属性必须返回false。
本质上,complete返回true如果图像已经完成加载,或者加载失败。因为我们只想要图像成功加载的情况,我们需要检查nauturalHeight属性:
IDL属性naturalWidth和naturalHeight必须返回
图像的固有宽度和高度,以CSS像素为单位,如果图像
可用,否则为0。
available的定义如下:
An img is always in one of the following states:
Unavailable - The user agent hasn't obtained any image data.
Partially available - The user agent has obtained some of the image data.
Completely available - The user agent has obtained all of the image data and at least the image dimensions are available.
Broken - The user agent has obtained all of the image data that it can, but it cannot even decode the image enough to get the image
dimensions (e.g. the image is corrupted, or the format is not
supported, or no data could be obtained).
When an img element is either in the partially available state or in
the completely available state, it is said to be available.
因此,如果图像是“破碎的”(加载失败),那么它将处于破碎状态,而不是可用状态,因此naturalHeight将为0。
因此,检查imgElement.complete && imgElement。== 0应该告诉我们图像是否已经成功加载。
您可以在img元素的W3C HTML规范或MDN上阅读更多相关内容。
实时网络检测器-检查网络状态,无需刷新页面:
(它不是jquery,但经过测试,100%工作:(在Firefox v25.0上测试))
代码:
<script>
function ImgLoad(myobj){
var randomNum = Math.round(Math.random() * 10000);
var oImg=new Image;
oImg.src="YOUR_IMAGELINK"+"?rand="+randomNum;
oImg.onload=function(){alert('Image succesfully loaded!')}
oImg.onerror=function(){alert('No network connection or image is not available.')}
}
window.onload=ImgLoad();
</script>
<button id="reloadbtn" onclick="ImgLoad();">Again!</button>
如果连接断开,请按“再次”按钮。
更新1:
自动检测,无需刷新页面:
<script>
function ImgLoad(myobj){
var randomNum = Math.round(Math.random() * 10000);
var oImg=new Image;
oImg.src="YOUR_IMAGELINK"+"?rand="+randomNum;
oImg.onload=function(){networkstatus_div.innerHTML="";}
oImg.onerror=function(){networkstatus_div.innerHTML="Service is not available. Please check your Internet connection!";}
}
networkchecker = window.setInterval(function(){window.onload=ImgLoad()},1000);
</script>
<div id="networkstatus_div"></div>