注意:此文于2010年编写,当时主流浏览器为IE 8/9 beta、Firefox 3.x和Chrome 4.x。请仅将其用于研究目的,我怀疑您无法将其复制/粘贴到现代浏览器中并顺利运行。
警告:现在是2017年,我偶尔还会收到关于此问题的提问,请仅将其用于研究目的。我目前不知道如何检测图像加载状态,但可能有更优雅的方法来实现它...至少我非常希望有。 我强烈建议不要在生产环境中使用我的代码而没有进行更多的研究。
警告第二部分 Electric Boogaloo:现在是2019年,大多数jQuery功能已内置于原生JS中。如果您仍在使用它,也许是时候停止并考虑前往MDN了解一些新的有趣的原生JS内容。
我有点晚到这个聚会,也许这个答案能帮助其他人……
如果您正在使用jQuery,请不要使用自带的事件处理程序(例如onclick/onmouseover等),最好完全停止使用它们。请使用他们在API中提供的事件方法。
这将在图像附加到页面主体之前进行警报,因为加载事件是在将图像加载到内存时触发的。它正在执行您要求它执行的操作:创建一个src为test.jpg的图像,在test.jpg加载完成后发出警报,然后将其附加到主体上。
var img = $('<img src="test.jpg" />');
img.load(function() {
alert('Image Loaded');
});
$('body').append(img);
在将图像插入主体后,这将触发警报并执行您指定的操作:创建图像,设置事件(未设置src,因此尚未加载),将图像附加到主体(仍未设置src),现在设置src...现在已加载图像,因此触发事件。
var img = $('<img />');
img.load(function() {
alert('Image Loaded');
});
$('body').append(img);
$img.attr('src','test.jpg');
var img = $('<img />');
img.bind({
load: function() {
alert('Image loaded.');
},
error: function() {
alert('Error thrown, image didn\'t load, probably a 404.');
}
});
$('body').append(img);
img.attr('src','test.jpg');
根据@ChrisKempen的要求...
以下是一种非事件驱动的方法,用于在DOM加载后确定图像是否损坏。这段代码是从StereoChrome的一篇文章中派生出来的,它使用naturalWidth、naturalHeight和complete属性来确定图像是否存在。
$('img').each(function() {
if (this.naturalWidth === 0 || this.naturalHeight === 0 || this.complete === false) {
alert('broken image');
}
});
naturalWidth
和naturalHeight
仅兼容IE9+,请参考以下链接以获取跨浏览器支持:http://stackoverflow.com/a/7869044/759452 和 http://www.jacklmoore.com/notes/naturalwidth-and-naturalheight-in-ie/ ,也可以参考http://css-tricks.com/snippets/jquery/get-an-images-native-width/。 - Adriano根据W3C规范, 只有BODY和FRAMESET元素提供了"onload"事件来附加。一些浏览器可能仍然支持它,但请注意,这不是实现W3C规范所必需的。
虽然这可能与讨论相关,但并不一定是你需要的答案,以下是相关讨论:
还有一些可能与您的需求相关的内容,尽管它可能并不相关,就是关于为任何动态加载的DOM元素支持合成"onload"事件的信息:
var img = new Image();
img.onload = function() {
alert('Done!');
}
img.src = '/images/myImage.jpg';
我认为onload
应该能够正常工作。您是否必须为图像生成标记,还是可以静态添加它们? 如果是后者,我建议采取以下措施:
<img src="foo.png" class="classNeededToHideImage" onload="makeVisible(this)">
或者,您可以使用window.onload
使所有图像立即可见 - window.onload
在所有外部资源加载完成后触发。
如果要动态添加图像,则首先必须等待DOM准备好进行修改,即使用jQuery或为不支持其本地实现的浏览器实现自己的DOMContentLoaded hack。
然后,您创建图像对象,分配onload
侦听器使它们可见和/或将它们添加到文档中。
更好的方法(但稍微复杂一些)是在脚本执行时立即创建并开始加载图像。在DOMContentLoaded上,您将需要检查每个图像的complete
以决定是立即将其添加到文档中还是等待图像的onload
侦听器触发。
好的,我会尝试总结这里各种部分答案(包括我的)。
看起来答案是使用onload,它“被广泛支持”,尽管根据标准不是必需的。请注意,特别是对于IE浏览器,您必须在设置src属性之前设置onLoad,否则当从缓存加载图像时可能不会触发onload事件。无论如何,这似乎是最佳实践:在开始触发事件之前设置您的事件处理程序。如果不支持onload,则应假定该功能不可用。
如果我没记错的话,在JavaScript中,图像标签有onload和onerror事件。
这里有一段有趣的代码,可以隐藏损坏的图片。
在样式标签中:
img.failed{
display:none;
}
使用img的onerror事件,我有一段JavaScript代码,它会将this.className设置为failed,如果出现错误,则会隐藏图像。
然而,我可能误解了您的目标。
HTML
<img id="myimage" src="http://farm4.static.flickr.com/3106/2819995451_23db3f25fe_t.jpg"/>
脚本
setTimeout(function(){
$('#myimage').attr('src','http://cdn.redmondpie.com/wp-content/uploads/2011/05/canarylogo.png').load(function(){
alert('Main Image Loaded');
$('#myimage').attr('src','image.jpg').bind({
load: function(){
alert('Image loaded.');
},
error: function(){
alert('Image not loaded.');
}
});
});
},1000);
JS Fiddle
看起来答案是在IE中使用onreadystatechange,在其他浏览器中使用onLoad。如果两者都不可用,则执行其他操作。onLoad更可取,但是正如下面的一个答案所指出的那样,当从缓存加载图像时,IE不会触发它。
使用数据URI是正确的方法。然而,使用SVG而不是GIF提供了更多的灵活性。您可以快速更改大小。只需在JavaScript控制台中运行以下命令:
var width = 1;
var height = 1;
'data:image/svg+xml;base64,' +
btoa(`<svg xmlns="http://www.w3.org/2000/svg" width="${width}" height="${height}"/>`);
示例输出:
data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxIiBoZWlnaHQ9IjEiLz4=
我写了一个快速的CodePen实用程序,可以创建任意尺寸的透明SVG图像。它非常基础,如果您想要添加颜色或其他功能到图像中,您需要修改它。
与单像素图像相比,最大的优势是它允许保持纵横比。这对于动态大小的图像非常重要,因为布局通常在src
更改为真实图像之前执行(如果这是预期目的)。在src更改之前,图像将是正方形的,这可能是不可取的。