JQuery - 如何检查图片何时加载完毕?

8

我在处理图像加载时遇到了一些问题。

有人告诉我以下函数可以解决问题,但是它并没有起作用。

$("#photos img:first").load(function (){
    alert("Image loaded!");
});

我的代码没有错误。我的脚本中其他部分都运行良好。

我的HTML代码如下:

<div id="photos">
    <img src="../sample1.jpg" style="background-color:#000033" width="1" height="1" alt="Frog!"/>
    <img src="../sample2.jpg" style="background-color:#999999" width="1" height="1" alt="Zooey!"/>
</div>

我使用的JQuery函数有误吗?值得注意的是,可见性设置为隐藏。但即使可见,也没有警报。
有任何想法吗?
4个回答

18
当图片加载完成时,会触发图片的load事件。需要注意的是,如果您在图片加载之前没有连接好处理程序,那么您的处理程序将不会被调用。浏览器会并行加载资源,因此即使在jQuery的ready事件中表示页面的DOM已经准备就绪,您也无法确定图片是否已经在代码运行时加载完毕。
您可以使用图片对象的complete属性来判断图片是否已经加载完成,例如:
var firstPhoto = $("#photos img:first");
if (firstPhoto[0].complete) {
    // Already loaded, call the handler directly
    handler();
}
else {
    // Not loaded yet, register the handler
    firstPhoto.load(handler);
}
function handler() {
    alert("Image loaded!");
}

如果浏览器真的实现了多线程加载,那么在此过程中可能会出现竞争条件,其中图像加载可能发生在不同于Javascript线程的线程上。

当然,如果您的选择器将匹配多个图像,则需要处理它;您的选择器似乎只应该匹配一个,所以...

编辑 此版本允许多个图像,并且我认为它处理了任何非Javascript竞争条件(当然,目前还没有Javascript竞争条件;在浏览器中,Javascript本身是单线程的[除非您使用新的web workers内容]):

function onImageReady(selector, handler) {
    var list;

    // If given a string, use it as a selector; else use what we're given
    list = typeof selector === 'string' ? $(selector) : selector;

    // Hook up each image individually
    list.each(function(index, element) {
        if (element.complete) {
            // Already loaded, fire the handler (asynchronously)
            setTimeout(function() {
                fireHandler.call(element);
            }, 0); // Won't really be 0, but close
        }
        else {
            // Hook up the handler
            $(element).bind('load', fireHandler);
        }
    });

    function fireHandler(event) {
        // Unbind us if we were bound
        $(this).unbind('load', fireHandler);

        // Call the handler
        handler.call(this);
    }
}

// Usage:
onImageReady("#photos img:first");

几点注意事项:

  • 回调函数不会返回event对象;如果需要的话你可以修改代码,但是当图片已经加载完成时,则没有必要返回事件对象,因此这个功能可能没什么实际用处。
  • 你也许可以使用one而不是bindunbind,但我喜欢保持代码清晰易懂,因为我有点小心眼。 :-)

3

使用ready事件代替load事件。


啊哈,天才。非常感谢。我要去查一下这两个之间的区别 :) - ComputerUser
你有关于图片ready事件的参考资料吗?我所知道的唯一ready事件是jQuery的“DOM准备就绪”事件,这完全不同。 - T.J. Crowder
1
@ThiefMaster:但是你是在说图片上确实有一个“ready”事件吗?我找不到任何提到它的地方,但也许我只是没有找对。如果能提供一个链接就太好了。 - T.J. Crowder
1
@ThiefMaster:可靠的、跨浏览器的?我不这么认为。事实上,我在Chrome上尝试了一下,什么也没得到。 - T.J. Crowder

0

试试这个:

    $("#images img:last").one("load",function(){
      //do something    
}

或者

    $("#images img:last").one("ready",function(){
      //do something    
}

请参考ThiefMaster的回复中的注释,我真的不认为有一个针对图像的ready事件,只有文档(jQuery提供的合成文档)才有。 - T.J. Crowder

0
$("#images img:last").on('load',function(){
  //do smth
});

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接