JQuery - 检查图像何时加载?

Jas*_*onS 8 jquery

我在加载图像时遇到了一些麻烦.

我被告知以下功能可以工作,但它没有做任何事情.

$("#photos img:first").load(function (){
    alert("Image loaded!");
});
Run Code Online (Sandbox Code Playgroud)

我的代码中没有错误.我脚本中的其他所有内容都很棒.

我的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>
Run Code Online (Sandbox Code Playgroud)

我有错误的JQuery功能吗?还应注意,可见性设置为隐藏.然而即使在可见时也没有警报.

有任何想法吗?

T.J*_*der 17

load当它的加载图像的事件被触发(DOH!),以及关键的是,如果你不挂钩处理程序之前加载,你的处理器将不会被调用.浏览器将并行加载资源,因此您无法确定(即使在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!");
}
Run Code Online (Sandbox Code Playgroud)

甚至可能存在竞争条件,如果所讨论的浏览器确实实现了多线程加载,其中图像加载可能发生在与Javascript线程不同的线程上.

当然,如果你的选择器匹配多个图像,你需要处理它; 你的选择器看起来应该只匹配一个,所以......

编辑该版本允许多个图像,我认为它处理任何非JavaScript竞态条件(当然,目前没有使用Javascript的比赛条件;使用Javascript本身就是在浏览器中单线程[除非你使用新的网络工作者的东西]):

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");
Run Code Online (Sandbox Code Playgroud)

几个笔记:

  • 回调没有得到event对象; 如果你喜欢的话,你可以修改它,但是当然,在图像已经加载的情况下没有事件,所以它的实用性有限.
  • 你可以使用one而不是bindunbind,但我喜欢清晰度,我是偏执狂.:-)