jQuery Ajax等待所有图片加载

时间:2022-03-28 03:59:15

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调用,它运行得很好。我使用success事件来显示数据。然而,一旦外部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);
    }
});

10 个解决方案

#1


40  

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

#2


17  

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 img elements have loaded.

这将把内容加载到元素中,并将其隐藏,然后在加载下的img元素之后重新显示它。

#3


10  

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

您可以将一些内容绑定到load事件,以知道它们何时完成:

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

Or you could use this plugin.

或者你可以用这个插件。

#4


4  

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

#5


1  

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

您可以使用与JavaScript和jQuery一起工作的imagesloaded插件,尝试在加载的内容上使用ajax success回调函数,并在不触发imagesloaded回调函数时隐藏所有内容,参见下面的示例代码

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

    }
});

#6


0  

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和窗口对象。

#7


0  

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

#8


0  

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

#9


0  

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

#10


-6  

i think the best is using this

我认为最好的办法就是用这个

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

#1


40  

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

#2


17  

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 img elements have loaded.

这将把内容加载到元素中,并将其隐藏,然后在加载下的img元素之后重新显示它。

#3


10  

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

您可以将一些内容绑定到load事件,以知道它们何时完成:

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

Or you could use this plugin.

或者你可以用这个插件。

#4


4  

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

#5


1  

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

您可以使用与JavaScript和jQuery一起工作的imagesloaded插件,尝试在加载的内容上使用ajax success回调函数,并在不触发imagesloaded回调函数时隐藏所有内容,参见下面的示例代码

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

    }
});

#6


0  

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和窗口对象。

#7


0  

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

#8


0  

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

#9


0  

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

#10


-6  

i think the best is using this

我认为最好的办法就是用这个

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