加载所有图像后的jquery或javascript函数

时间:2016-07-23 13:31:55

标签: javascript jquery

目前我正在使用$( window ).load(function()在所有图片加载后触发我的操作。

但有时当外部脚本或其他东西需要很长时间才能加载时,即使图像已经加载,我的函数也会很晚才会启动。

所以我想找到像$( document ).ready(function()这样的函数,它等待所有加载的图像,然后运行我的函数。 我不需要整个文档准备就绪,我只需要为我的功能加载图像。

有这样的东西吗?

1 个答案:

答案 0 :(得分:4)

是的,这实际上相当容易。图片元素上有一个complete标记,当它们完成时会触发loaderror个事件。所以我们可以这样做(参见下面有关表观复杂性的说明)

function getAllImagesDonePromise() {
    // A jQuery-style promise we'll resolve
    var d = $.Deferred();

    // Get all images to start with (even complete ones)
    var imgs = $("img");

    // Add a one-time event handler for the load and error events on them
    imgs.one("load.allimages error.allimages", function() {
        // This one completed, remove it
        imgs = imgs.not(this);
        if (imgs.length == 0) {
            // It was the last, resolve
            d.resolve();
        }
    });

    // Find the completed ones
    var complete = imgs.filter(function() { return this.complete; });

    // Remove our handler from completed ones, remove them from our list
    complete.off(".allimages");
    imgs = imgs.not(complete);
    complete = undefined; // Don't need it anymore

    // If none left, resolve; otherwise wait for events
    if (imgs.length == 0) {
        d.resolve();
    }

    // Return the promise for our deferred
    return d.promise();
}

每当你需要检查时,就像这样使用它:

getAllImagesDonePromise().then(function() {
    // They're all done
});

你可以在你放在正文末尾的脚本中使用它,就在结束</body>标记之前(如果你愿意,可以在ready回调中)。

你可能想知道“完整”图像的复杂性。为什么我们将事件挂钩,然后删除它们并取消事件?这是为了应对竞争条件。虽然浏览器在单个UI线程上运行主JavaScript,但浏览器 不是单线程。它可以随时完成加载图像并设置其complete属性。如果发生这种情况,我们尚未与该图片上的load / error事件挂钩,我们将不会收到通知。因此,如果我们首先过滤掉已完成的图像,然后将事件挂钩到剩余的图像上,那些在这些代码行之间完成的图像(再次:我们的代码是单线程的,浏览器不是)永远不要开火。所以我们挂钩事件,然后过滤掉已完成的事件,然后处理我们收到的任何事件。