2011-01-23 82 views
34

我试图用jQuery执行Ajax调用,它运行良好。我使用成功事件来显示数据。然而,似乎一旦外部HTML文件被加载,成功就会被触发。如果有大图像,它们会在显示后继续加载。是否有一种方法可以在所有内容完全加载后显示内容?下面是代码:jQuery Ajax等到所有图像加载

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

回答

39

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

} 

然后你可以使用它是这样的:

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

希望这对别人有帮助的。

请注意,使用上面的代码,如果其中一个图像错误(例如,由于URL错误),承诺无论如何解决,错误被忽略。这可能是你想要的,但是,根据你的情况,如果图片加载失败,你可能会想放弃你正在做的任何事情。在这种情况下,可以按如下方式更换的onerror行:

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

,赶上这样的错误:

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

考虑使用jQuery的.load()

其中有一段描述:

负载事件被发送到一个元素时,它和所有子元素已完全加载。这个事件可以发送到与URL相关的任何元素:图像,脚本,框架,iframe和窗口对象。

+0

事情是我不能关闭异步调用带有负荷和设置缓存选项权利? – robs 2011-01-23 16:27:31

10

您可以绑定的东西给负载事件,知道他们在做的时候:

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

或者你可以使用this plugin

+1

哦,上帝,你不知道有多少帮助我,我正在寻找解决方案几个小时...非常感谢你:D – Linas 2012-06-29 08:53:31

+5

.on()明显推荐.bind()现在 – UpTheCreek 2013-03-29 10:15:09

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

我认为最好的就是采用这种

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

这种方法是更一般的,但我觉得它很棒! – 2011-07-30 06:09:04

+6

这将不起作用,因为`$(document).ready()`和`$(window).load()`在AJAX请求后不会触发。 – Andreyco 2012-03-28 10:12:07

16

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

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

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

    } 
}); 

这将东西装入你的元素,隐藏它,然后将其重新显示一次后裔img元素已加载。

4

这将触发对单独每IMG负载:

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

我用:

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

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

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

您可以使用imagesloaded插件是使用JavaScript和jQuery的工作,尽量里面AJAX使用上加载的内容success回调函数,隐藏所有内容,同时imagesloaded回调函数不触发,请参见下面的示例代码

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

    } 
}); 
0

当Daniel的解决方案的插件找不到图片时,我发现了一个小错误。

万一一些别的得到了同样的问题:

变化:

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

要:

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