jQuery Ajax 等待所有图像加载完毕

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4774746/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-26 17:54:55  来源:igfitidea点击:

jQuery Ajax wait until all images are loaded

jqueryajaxloading

提问by robs

I'm trying to perform an Ajax call with jQuery which is working well. I use the success event to display the data. It seems however that success gets triggered as soon as the external HTML file gets loaded. If there are large images they keep loading after they're shown. Is there a way to display the content after everything is fully loaded? Here is the code:

我正在尝试使用运行良好的 jQuery 执行 Ajax 调用。我使用成功事件来显示数据。然而,一旦加载外部 HTML 文件,似乎就会触发成功。如果有大图像,它们会在显示后继续加载。有没有办法在所有内容完全加载后显示内容?这是代码:

$('#divajax').html('<br><div style="text-align: center;"><img src="res/ajax-loader.gif"></div>');
$.ajax({
    cache: false,
    url: 'ajax/content.php',
    success: function(data) {
          $('#divajax').html(data);
    }
});

回答by Daniel Howard

The plugin that @alex wrote didn't work for me for some reason... I couldn't figure out why. But his code did inspire me to come up with a more lightweight solution that is working for me. It uses jquery promises. Please note that unlike @alex 's plugin, this doesn't attempt to account for background images on elements, only img elements.

@alex 写的插件出于某种原因对我不起作用......我不知道为什么。但他的代码确实激发了我想出一个更适合我的轻量级解决方案。它使用 jquery 承诺。请注意,与@alex 的插件不同,这不会尝试考虑元素上的背景图像,仅考虑 img 元素。

// Fn to allow an event to fire after all images are loaded
$.fn.imagesLoaded = function () {

    // get all the images (excluding those with no src attribute)
    var $imgs = this.find('img[src!=""]');
    // if there's no images, just return an already resolved promise
    if (!$imgs.length) {return $.Deferred().resolve().promise();}

    // for each image, add a deferred object to the array which resolves when the image is loaded (or if loading fails)
    var dfds = [];  
    $imgs.each(function(){

        var dfd = $.Deferred();
        dfds.push(dfd);
        var img = new Image();
        img.onload = function(){dfd.resolve();}
        img.onerror = function(){dfd.resolve();}
        img.src = this.src;

    });

    // return a master promise object which will resolve when all the deferred objects have resolved
    // IE - when all the images are loaded
    return $.when.apply($,dfds);

}

Then you can use it something like this:

然后你可以像这样使用它:

$.ajax({
    cache: false,
    url: 'ajax/content.php',
    success: function(data) {
        $('#divajax').html(data).imagesLoaded().then(function(){
            // do stuff after images are loaded here
        });
    }
});

Hopefully that's helpful for someone.

希望这对某人有帮助。

Note that using the above code, if one of the images errors (eg because the URL was wrong), the promise is resolved anyway and the error is ignored. This might be what you want, but, depending on your situation, you might instead want to abort whatever you are doing if an image fails to load. In which case you could replace the onerror line as follows:

请注意,使用上面的代码,如果图像之一错误(例如,因为 URL 错误),则无论如何都会解决承诺并忽略错误。这可能是您想要的,但是,根据您的情况,如果图像加载失败,您可能想要中止正在执行的任何操作。在这种情况下,您可以按如下方式替换 onerror 行:

img.onerror = function(){dfd.reject();}

And catch the error like this:

并捕获这样的错误:

$('#divajax').html(data).imagesLoaded().done(function(){
    // do stuff after all images are loaded successfully here
}).fail(function(){
    // do stuff if any one of the images fails to load
});

回答by alex

You could use my jQuery plugin, waitForImages...

你可以使用我的 jQuery 插件,waitForImages...

$.ajax({
    cache: false,
    url: 'ajax/content.php',
    success: function(data) {

         $('#divajax').html(data).hide().waitForImages(function() {
             $(this).show();
         });

    }
});

This will load the stuff into your element, hide it, and then reshow it once descendent imgelements have loaded.

这会将内容加载到您的元素中,隐藏它,然后在后代img元素加载后重新显示它。

回答by Lyle Pratt

You can bind something to the load events to know when they're done:

您可以将某些内容绑定到加载事件以了解它们何时完成:

$('<img>').bind('load', function() {
    $(this).appendTo('body');
});

Or you could use this plugin.

或者你可以使用这个插件

回答by Aureliano Far Suau

this triggers on every img load separately:

这会分别在每个 img 加载时触发:

$('img').on('load', function() {
      // do something
});

i used:

我用了:

var loaded = 0;
$('img').on('load', function() {
   loaded++;
   if(loaded == $('img').length){
      // do something
   }
});

回答by Girish

You can use imagesloadedplugin that is work with JavaScript and jQuery, try to use inside ajax successcallback function on loaded content, and hide all content while imagesloadedcallback function not trigger, see below sample code

您可以使用imagesloaded适用于 JavaScript 和 jQuery 的插件,尝试success在加载的内容上使用内部 ajax回调函数,并在imagesloaded不触发回调函数的情况下隐藏所有内容,请参见下面的示例代码

$.ajax({
    cache: false,
    url: 'ajax/content.php',
    success: function(data) {
        var $divajax = $('#divajax').html(data).hide();
        $divajax.imagesLoaded(function() {
             $divajax.show();
         });

    }
});

回答by Milton Pena

I've got a small bug when no images are found by the plugin from Daniel's solution.

当 Daniel 的解决方案中的插件没有找到图像时,我遇到了一个小错误。

Just in case some else get the same issue:

以防万一其他人遇到同样的问题:

Change:

改变:

// if there's no images, just return an already resolved promise
if (!$imgs.length) {return $.Deferred.resolve().promise();}

To :

到 :

// if there's no images, just return an already resolved promise
    if (!$imgs.length) {
        var dfd = $.Deferred();
        return dfd.resolve().promise();
    }

回答by Duy Phan

Try this code. It works fine.

试试这个代码。它工作正常。

$.ajax({
    url: "../api/listings",
    type: 'GET',
    success: function (html) {
        $('#container').append(html);
        $('#container img').on('load', function(){console.log('images loaded')});
    };
});

回答by sv_in

$('#divajax').html('<br><div style="text-align: center;"><img src="res/ajax-loader.gif"></div>').load(function() {
$.ajax({
    cache: false,
    url: 'ajax/content.php',
    success: function(data) {
          $('#divajax').html(data);
    }
});
});

回答by AlanFoster

Look into using jquery's .load()

研究使用 jquery 的 .load()

Which has a description of :

其中有一个描述:

The load event is sent to an element when it and all sub-elements have been completely loaded. This event can be sent to any element associated with a URL: images, scripts, frames, iframes, and the window object.

当一个元素和所有子元素都被完全加载时,加载事件被发送到一个元素。此事件可以发送到与 URL 关联的任何元素:图像、脚本、框架、iframe 和 window 对象。

回答by lilsizzo

i think the best is using this

我认为最好的是使用这个

$(window).ready(function(){ //load your ajax})