简体   繁体   English

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

[英]jquery or javascript function after all images loaded

currently I am using the $( window ).load(function() to fire my action after all images loaded. 当前我正在使用$( window ).load(function()在加载所有图像后触发动作。

But sometimes when a external script or something else need a very long time to load, my functions fire very late even when the images are already loaded. 但是有时候,当外部脚本或其他内容需要很长时间加载时,即使已加载图像,我的函数也会启动得很晚。

So I would like to find a function like $( document ).ready(function() which waits untill all images loaded and than run my function. I dont need the whole document to be ready, I just need the images to be loaded for my function. 所以我想找到一个像$( document ).ready(function() ,它会等到所有图像加载完毕后再运行我的函数,我不需要准备整个文档,我只需要为这些图像加载我的功能。

Is there anything like this? 有没有这样的东西?

Yes, it's actually fairly easy to do. 是的,这实际上很容易做到。 Image elements have a complete flag on them, and they fire load or error events when they complete. 图像元素上具有complete标志,并且它们在完成时会触发loaderror事件。 So we can do this (see note below about the apparent complexity) : 因此,我们可以执行此操作(请参阅以下有关明显复杂性的注释)

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();
}

And use it like this whenever you need to check: 并在需要检查时像这样使用它:

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

You could use it in a script you've put at the end of the body, just before the closing </body> tag (or in a ready callback if you prefer). 您可以在放在正文末尾</body>标记之前的脚本中使用它(或者,如果愿意, readyready回调中使用它)。

You're probably wondering about the complexity around "complete" images. 您可能想知道“完整”图像的复杂性。 Why do we hook an event on them, then remove them and unhook the event? 我们为什么要在其上挂一个事件,然后将其删除并取消挂起事件? It's to deal with race conditions. 这是为了应对比赛条件。 Although the browser runs the main JavaScript on a single UI thread, the browser is not single-threaded. 尽管浏览器在单个UI线程上运行主要的JavaScript,但浏览器 不是单线程的。 It can finish loading an image and set its complete property at any time. 它可以随时完成图像加载并设置其complete属性。 If we're not already hooked to the load / error event on that image when that happens, we won't get notification. 如果发生这种情况时我们还没有迷上该图像上的load / error事件,则不会收到通知。 So if we filtered out completed images first, then hooked the events on the remaining ones, any image that completed between those lines of code (again: our code is single-threaded, the browser is not) would never fire the event. 因此,如果我们先过滤掉完成的图像,然后将事件挂在其余的图像上,那么在这些代码行之间完成的任何图像(同样:我们的代码是单线程的,浏览器不是)将永远不会触发该事件。 So we hook the events, then filter out completed ones, then deal with any events we get back. 因此,我们挂接事件, 然后过滤掉已完成的事件,然后处理返回的所有事件。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM