仅在AJAX加载了新内容的所有字节后才执行操作

时间:2013-06-05 12:46:11

标签: jquery html ajax

我正在尝试使用AJAX从服务器中获取一些内容,我不知道加载可能需要多长时间,因为它可能很重。所以我创建了一个每次调用AJAX函数时出现的加载gif,但是我想在加载AJAX响应后淡出它并在内容部分中淡出。

HTML

<div id="loading"><img src="loading.gif" /></div>
<div id="content"></div>

这就是我的尝试:

$(elm).click(function(){
  $('#loading').show();
  $('#content').fadeOut();
  $.ajax({
      url:'posts.php'
      data:{id:id_post},
      method:"POST",
      success:function(response){
        $('#content').load(response, function(){
          $('#content').html(response);
          $('#content').fadeIn();
          $('#loading').hide();
        });
      }
  });
});

我知道这是错误的,因为在.load(param1, function(data){})中,param1应该是要加载的参考文件而不是带字符串的变量,它似乎有用,但console.log(data)会返回一个未找到的错误,所以我相信这不是这样做的方法。

简而言之:我想fadeIn()我的div和fadeOut()我的加载当且仅当加载了AJAX响应的每个字节时,如果代码已准备好但是已加载,例如a <img>标记内的大图片。

有什么想法吗?感谢

4 个答案:

答案 0 :(得分:2)

如果您的AJAX响应是一大块HTML,其中包含您放在页面上的<img>标记,并且您想要检测何时加载此图像,则应该执行额外的操作。

您应该将图像中的响应分为预加载,以及使用该图像的原始html。您可以使用这样的JSON响应:

{
 "image": "url_to_big_image.jpg", 
 "html": "<img src=\"url_to_big_image.jpg\">"
}

您最喜欢的后端语言可能有一种将对象/数组转换为JSON的方法。

然后,当您的AJAX请求完成后,您可以执行以下操作:

var img = $('<img/>')
img[0].src = response.image // this pre-loads the image

img.load(function() {
    // now the image has been pre-loaded
    $('#content').html(response.html)
    $('#content').fadeIn()
    $('#loading').hide()
})

多个图像

要为多个图像执行此操作,您可以将图像放在JSON中的数组中:

{
 "images": ["url_to_big_image.jpg", "second_image.jpg"], 
 "html": "<img src=\"url_to_big_image.jpg\"> <img src=\"second_image.jpg\">"
}

然后在javascript中循环遍历它们,并跟上已加载的数量。如果已加载所有图像,您可以显示内容:

var show_content = function() {

    // only show content if all images are loaded
    if(images_loaded == response.images.length) {
        $('#content').html(response.html)
        $('#content').fadeIn()
        $('#loading').hide()
    }

}

var images_loaded = 0

for(var img_url in response.images) {

    var img = $('<img/>')
    img[0].src = img_url // preload image

    img.load(function() { // when image is pre-loaded
        images_loaded++ // increase images_loaded
        show_content() // show content if all images are loaded
    })

}

我没有测试过这段代码,所以你可能需要更改一些东西才能使它工作,但这是关于这个想法。

答案 1 :(得分:1)

基于API你可以做到

$(elm).click(function(){
  $('#loading').show();
  $('#content').fadeOut();
  $('#content').load('posts.php',
          {id:id_post},
          function(response, status, xhr){
              $('#content').fadeIn();
              $('#loading').hide();
          }
   );
});

$.load已将#content的html设置为响应。

答案 2 :(得分:0)

jQuery load函数从服务器加载数据并将url作为第一个参数。请参阅documentation

所以我认为你应该这样做:

success:function(response){
    $('#content').html(response)
    $('#content').fadeIn();
    $('#loading').hide();
}

答案 3 :(得分:0)

您可以尝试{未经测试}:

success: function (response) {
     var $tmp = $($.trim(response)),
         $l_elems = $tmp.find('img, script'),  //find will not work if elements not nested inside a container. In this case use a fake div as container and nesting elements inside it
         tot = $l_elems.length,
         i = 0;
     $l_elems.one('load', function () { //here using one, not on
         i++;
         if (i === tot) {
             $('#loading').hide();
             $('#content').append($l_elems).fadeIn();
         }
     }).each(function () {
         if (this.complete) $(this).load();
     });
 }