独立于浏览器的方式来检测何时加载图像

在IE中,你可以预先更改。 有负载,但我读了可怕的事情 。 jQuery用“ready”很好地包装了DOM的加载事件。 我似乎可能只是无知的另一个漂亮的图书馆的图像加载的实现。

上下文是我dynamic生成图像(通过服务器callback),可能需要一些时间下载。 在我的IE-only代码中,我设置了img元素的src,然后当onreadystatechange事件触发“完成”状态时,我将它添加到DOM,以便用户看到它。

我会很满意一个“原生”的JavaScript解决scheme,或者指向一个图书馆的指针。 那里有那么多的图书馆,我敢肯定,这只是我不知道正确的一个。 也就是说,我们已经是jQuery用户了,所以我不急于添加一个非常大的库来获得这个function。

注:我在2010年写了这个,野外的浏览器是IE 8/9testing版,Firefox 3.x和Chrome 4.x. 请仅用于研究目的,我怀疑你可以复制/粘贴到一个现代的浏览器,并没有问题的工作。

警告:现在是2017年,我现在仍然得到这一点,请只用于研究目的。 我目前不知道如何检测图像加载状态,但可能比这更优美的方式做到这一点…至less我真的很希望有这样的。 我强烈build议不要在生产环境中使用我的代码而不做更多的研究。


这个派对我有点晚了,也许这个答案会帮助别人…

如果你正在使用jQuery,不用担心股票事件处理程序(onclick / onmouseover / etc),实际上是完全停止使用它们。 使用他们在API中提供的事件方法。


在将图像附加到主体之前,这将会发出警报,因为当图像被加载到内存中时会触发加载事件。 它正在做你正在做的事情:用test.jpg的src创build一个图像,当test.jpg加载时做一个警报,然后将其附加到主体。

var img = $('<img src="test.jpg" />'); img.load(function() { alert('Image Loaded'); }); $('body').append(img); 

这将会在图像插入到主体后发出警报,再次按照你的要求:创build一个图像,设置一个事件(没有设置src,所以它没有加载),将图像附加到主体(仍然没有src),现在设置src …现在图像被加载,所以事件被触发。

 var img = $('<img />'); img.load(function() { alert('Image Loaded'); }); $('body').append(img); $img.attr('src','test.jpg'); 

您当然也可以添加一个error handling程序,并使用bind()合并一堆事件。

 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和完整属性来确定图像是否存在。

 $('img').each(function() { if (this.naturalWidth === 0 || this.naturalHeight === 0 || this.complete === false) { alert('broken image'); } }); 

根据W3C规范只有 BODY和FRAMESET元素提供了一个“onload”事件来附加。 有些浏览器无论如何都支持它,但请注意,不需要实现W3C规范。

这个讨论可能与这个讨论有关,但不一定是你所需要的答案,这个讨论是:

当图像在caching中时,Image.onload事件不会在Internet Explorer上触发


还有一些可能与您的需求有关的信息 ,虽然它可能不是,但是这个信息支持任何dynamic加载的 DOM元素的合成“onload”事件:

我怎样才能确定一个dynamic创build的DOM元素是否已经添加到DOM?

我发现的唯一可靠的方法就是在客户端这样做这一切…

 var img = new Image(); img.onload = function() { alert('Done!'); } img.src = 'http://img.dovov.commyImage.jpg'; 

我认为onload应该可以正常工作。 你必须为图像生成标记,还是可以静态添加它们? 如果后者,我会build议如下:

 <img src="foo.png" class="classNeededToHideImage" onload="makeVisible(this)"> 

或者,您可以使用window.onload使所有图像一次显示 – window.onload在所有外部资源加载完成后触发。

如果你想dynamic添加图片,你首先必须等待DOM准备好被修改,例如使用jQuery或者实现你自己的DOMContentLoaded hack浏览器,这些浏览器本身不支持它。

然后,创build图像对象,分配onload监听器以使其可见和/或将其添加到文档中。

更好的(但稍微复杂一些)是在脚本执行时立即创build并开始加载图像。 在DOMContentLoaded上,您必须检查每个图像是否complete以决定是将它们立即添加到文档还是等待图像的onload侦听器触发。

好的,我会尽量总结这里的各种部分答案(包括我的)。

看来答案是使用onload,这是“广泛支持”,虽然没有按照标准正式要求。 请注意,对于特别是IE,您必须在设置src属性之前设置onLoad,否则从caching中加载图像时可能不会触发onload。 在任何情况下,这似乎都是最佳实践:在开始触发事件之前设置事件处理程序。 在不支持onload的情况下,应该假定该function根本不可用。

看来答案是在IE中使用onreadystatechange,而在其他浏览器中使用onLoad。 如果没有一个可用,则执行其他操作。 onLoad将是可取的,但如下面答案之一所述,IE从caching中加载图像时不会触发它。

如果我没有错误的JavaScript图像标签有onload和onerror事件

这里是一个隐藏的位代码我做隐藏破碎的图像

在一个风格的标签

 img.failed{ display:none; } 

使用img onerror我有一块JavaScript做了this.className =失败,它会隐藏图像,如果它出错

不过,我可能误解了你的目标

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小提琴

http://jsfiddle.net/gerst20051/sLge3/

使用数据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实用工具放在一起, 以创build具有任意维度的透明SVG 。 这是非常基本的,所以你需要修改它,如果你想添加颜色或其他function的形象。

与单像素图像相比,最大的优势是可以保留宽高比。 这对于dynamic大小的图像很重要,因为在src更改为真实图像之前经常执行布局(如果这是预期的目的)。 在src改变之前,图像将是方形的,这可能是不希望的。