与浏览器无关的方式来检测何时加载图像

时间:2009-05-04 19:17:55

标签: javascript dom

在IE中,您可以onreadystatechange。有载入,但我读了scary things。 jQuery用“就绪”很好地包装了DOM的加载事件。我似乎只是不知道另一个很好的库的图像加载实现。

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

我对“原生”JavaScript解决方案或指向执行工作的库的指针感到满意。那里有很多图书馆,我确信这是我不知道正确的图书馆的情况。也就是说,我们已经是jQuery用户了,所以我并不急于添加一个非常大的库来获得这个功能。

9 个答案:

答案 0 :(得分:47)

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

警告: 2017年,我现在仍然可以获得积分,请仅将其用于研究目的。我目前不知道如何检测图像加载状态,但有可能比这更优雅的方式...至少我真的希望有。我强烈建议不要在没有更多研究的情况下在生产环境中使用我的代码。


我参加这个派对有点晚了,也许这个答案可以帮助别人......

如果您正在使用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,因此未加载),将图像附加到正文(仍然没有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和完整属性来确定图像是否存在。

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

答案 1 :(得分:11)

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

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

  

Image.onload event does not fire on Internet Explorer when image is in cache


可能与您的需求相关的其他内容(尽管可能不是),这是关于为任何动态加载的 DOM元素支持合成“onload”事件的信息:

How can I determine if a dynamically-created DOM element has been added to the DOM?

答案 2 :(得分:5)

我发现的唯一可靠的方法是在客户端这样做所有这些......

var img = new Image();
img.onload = function() {
  alert('Done!');
}
img.src = '/images/myImage.jpg';

答案 3 :(得分:3)

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

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

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

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

然后,您创建图像对象,指定onload个侦听器以使其可见和/或将它们添加到文档中。

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

答案 4 :(得分:3)

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

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

答案 5 :(得分:1)

如果我在javascript中没有弄错,那么图片标记的事件是onload和onerror

这里是我用来隐藏破碎图像的一段代码

在样式标记中

img.failed{
   display:none;
}

使用img onerror我有一段javascript做this.className =失败 如果错误,它会隐藏图像

然而,我可能误解了你的目标

答案 6 :(得分:1)

似乎答案是在IE中使用onreadystatechange,在其他浏览器中使用onLoad。如果两者都不可用,请做其他事情。 onLoad会更好,但IE从缓存中加载图像时不会触发它,如下面的答案中所述。

答案 7 :(得分:1)

<强> HTML

<img id="myimage" src="http://farm4.static.flickr.com/3106/2819995451_23db3f25fe_t.jpg"/>​

<强> SCRIPT

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

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

答案 8 :(得分:0)

使用数据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=

我把a quick CodePen utility to create transparent SVGs with arbitrary dimensions放在一起。它非常基础,因此如果您想为图像添加颜色或其他功能,则需要对其进行修改。

单像素图像的最大优势在于它可以保留纵横比。这对于动态大小的图像很重要,因为布局通常在src更改为真实图像之前执行(如果这是预期目的)。直到src改变,图像将是方形的,这可能是不合需要的。