javascript-与浏览器无关的方法来检测图像何时已加载

在IE中,您可以onreadystatechange。 有负载,但是我读了一些可怕的东西。 jQuery用“ ready”很好地包装了DOM的load事件。 似乎我只是不了解另一个漂亮的库对图像加载的实现。

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

我对“本机” JavaScript解决方案或指向可以完成工作的库的指针感到满意。 那里有很多图书馆,我敢肯定这是我的一个案例,只是不了解正确的图书馆。 就是说,我们已经是jQuery用户,因此我不急于为了获得此功能而添加非常大的库。

Sebastian Good asked 2019-11-15T19:03:15Z
9个解决方案
48 votes

注意:我是在2010年写的,当时的浏览器是IE 8/9 beta,Firefox 3.x和Chrome4.x。 请仅将此用于研究目的,我怀疑您可以将其复制/粘贴到现代浏览器中并使其正常工作。

警告:现在是2017年,我仍然时不时地对此有所了解,请仅将其用于研究目的。 我目前不知道如何检测图像加载状态,但是可能有比这更优雅的方法了……至少我非常希望有这种方法。 我强烈建议不要在没有更多研究的情况下在生产环境中使用我的代码。

警告第二部分Electric Boogaloo:现在是2019年,大多数jQuery功能现在已内置在vanilla JS中。 如果您仍在使用它,可能是时候停止并考虑前往MDN并阅读Vanilla JS提供的一些有趣的新东西了。


我参加这个聚会有点晚了,也许这个答案会对别人有所帮助...

如果您使用的是jQuery,请不要理会股票事件处理程序(onclick / onmouseover / etc),实际上完全不要再使用它们了。 使用他们在API中提供的事件方法。


这将在将图像附加到主体之前发出警报,因为在将图像加载到内存中时会触发加载事件。 它正是按照您的指示进行操作:使用test.jpg的src创建一个图像,当test.jpg加载时发出警报,然后将其附加到正文中。

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

在将图像插入到主体之后,这将提醒您,再次执行您告诉它的操作:创建图像,设置事件(未设置src,因此尚未加载),将图像附加到主体(仍然 no src),现在设置src ...现在加载了图像,因此触发了事件。

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

当然,您还可以添加一个错误处理程序,并使用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和complete属性确定图像是否存在。

$('img').each(function() {
    if (this.naturalWidth === 0 || this.naturalHeight === 0 || this.complete === false) {
        alert('broken image');
    }
});
Paul J answered 2019-11-15T19:04:31Z
11 votes

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

此讨论可能与该讨论有关,但不一定是您需要的答案:

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


可能与您的需求相关的其他信息(尽管可能与您的需求无关)是有关为任何动态加载的DOM元素支持综合“ onload”事件的以下信息:

如何确定是否已将动态创建的DOM元素添加到DOM?

Jason Bunting answered 2019-11-15T19:05:21Z
6 votes

我发现的唯一可靠的方法是像这样在客户端进行所有操作...

var img = new Image();
img.onload = function() {
  alert('Done!');
}
img.src = '/images/myImage.jpg';
Josh Stodola answered 2019-11-15T19:05:44Z
3 votes

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

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

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

如果要动态添加图像,则首先必须等待DOM准备好被修改,即使用jQuery或为不支持它的浏览器实现自己的DOMContentLoaded hack。

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

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

Christoph answered 2019-11-15T19:06:34Z
3 votes

好的,我会在这里尝试总结各种局部答案(包括我的答案)。

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

Sebastian Good answered 2019-11-15T19:07:05Z
1 votes

答案似乎是在IE中使用onreadystatechange,在其他浏览器中使用onLoad。 如果没有人可用,请执行其他操作。 最好使用onLoad,但从缓存中加载图像时,IE不会触发它,如以下答案之一所述。

Sebastian Good answered 2019-11-15T19:07:29Z
1 votes

如果我在JavaScript中没有记错,则图像标签会包含事件onload和onerror

这是我用来隐藏残破图像的有趣代码

在样式标签中

img.failed{
   display:none;
}

使用img onerror我有一块JavaScript做到了这一点。className = failed如果出错,它将隐藏图像

但是我可能误会了你的目标

Jim answered 2019-11-15T19:08:18Z
1 votes

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/]

Andy answered 2019-11-15T19:08:52Z
0 votes

使用数据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更改之前,图像将是方形的,这可能是不可取的。

Zenexer answered 2019-11-15T19:09:31Z
translate from https://stackoverflow.com:/questions/821516/browser-independent-way-to-detect-when-image-has-been-loaded