如何在Ajax请求期间显示处理动画/旋转器?

20

我希望在我的AJAX POST请求处理期间显示一个基本的加载图标或处理动画。我正在使用JQuery和Python。我查看了文档,但无法确定应该将ajaxStart和ajaxStop函数放置在哪里。

以下是我的js代码:

    <script type="text/javascript">
      $(function() {  
        $('.error').hide();  
        $("#checkin-button").click(function() { 
          var mid = $("input#mid").val();
          var message = $("textarea#message").val();
          var facebook = $('input#facebook').is(':checked');
          var name = $("input#name").val();
          var bgg_id = $("input#bgg-id").val();
          var thumbnail = $("input#thumbnail").val();
          var dataString = 'mid='+mid+'&message='+message+'&facebook='+facebook+'&name='+name+'&bgg_id='+bgg_id+'&thumbnail='+thumbnail;  
          $.ajax({  
            type: "POST",  
            url: "/game-checkin",  
            data: dataString,  
            success: function(badges) {  
            $('#checkin-form').html("<div id='message'></div><div id='badges'></div>");  
            $('#message').html("<h2><img class=\"check-mark\" src=\"/static/images/check-mark.png\"/>You are checked in!</h2>");  
            $.each(badges, function(i,badge) {
              $('#badges').append("<h2>New Badge!</h2><p><img class='badge' src='"+badge.image_url+"'><span class='badge-title'>"+badge.name+"</span></p>");  
            });
          }
       });
       return false;
     });  
    });
  </script>

有很多好的答案可供选择。我已经尝试了大部分被回答的方法,所有方法似乎都能很好地工作。有很多种方法可以解决这个问题。谢谢! - Will Curran
5
不要杀猫,这是残忍的行为,它们也不喜欢被这样对待。 - bharal
7个回答

30
$.ajax({
  type: "POST",
  url: "/game-checkin",
  data: dataString,
  beforeSend: function () {
    // ... your initialization code here (so show loader) ...
  },
  complete: function () {
    // ... your finalization code here (hide loader) ...
  },
  success: function (badges) {
    $('#checkin-form').html("<div id='message'></div><div id='badges'></div>");
    $('#message').html("<h2><img class=\"check-mark\" src=\"/static/images/check-mark.png\"/>You are checked in!</h2>");
    $.each(badges, function (i, badge) {
      $('#badges').append("<h2>New Badge!</h2><p><img class='badge' src='" + badge.image_url + "'><span class='badge-title'>" + badge.name + "</span></p>");
    })
  }
});

http://api.jquery.com/jQuery.ajax/:

以下是$.ajax()提供的回调方法:

在发送请求之前将会调用beforeSend回调函数,它接收jqXHR对象和设置参数作为参数。 如果请求失败,则会按注册顺序调用错误回调函数。它们接收jqXHR对象、表示错误类型的字符串以及(如适用)异常对象。一些内置错误将在异常对象中提供一个字符串:"abort","timeout","No Transport"。 在成功接收响应数据后立即调用dataFilter回调函数。它接收返回的数据和dataType的值,并必须返回(可能已更改的)数据以传递给success。 如果请求成功,则按照注册顺序调用成功回调函数。它们接收返回的数据、包含成功代码的字符串以及jqXHR对象。 不管是失败还是成功,当请求结束时将会按照注册顺序触发complete回调函数。它们接收jqXHR对象和包含成功或错误代码的字符串。

请注意代码中添加的beforeSendcomplete方法。

希望这有帮助。


2
beforeSend 是一个奇怪的地方放置 spinner 代码。它是用于修改 XHR 对象,而不是操作 DOM。您可以在调用 $.ajax 之前简单地添加 spinner。现在,您可能希望使用 .always promise 方法停止 spinner。 - mpen

7
如果你使用的是jQuery 1.5,你可以通过一个预过滤器来实现优美、不显眼和通用化的操作。让我们为此编写一个非常简单的插件:
(function($) {

    var animations = {};

    $.ajaxPrefilter(function( options, _, jqXHR ) {
        var animation = options.animation && animations[ options.animation ];
        if ( animation ) {
            animation.start();
            jqXHR.then( animation.stop, animation.stop );
        }
    });

    $.ajaxAnimation = function( name, object ) {
        if ( object ) {
            animations[ name ] = object;
        }
        return animations[ name ];
    };

})( jQuery );

您可以按照以下步骤安装动画:
jQuery.ajaxAnimation( "spinner" , {
    start: function() {
        // code that starts the animation
    }
    stop: function() {
        // code that stops the animation
    }
} );

然后,在您的ajax选项中指定动画:

jQuery.ajax({
    type: "POST",
    url: "/game-checkin",
    data: dataString,
    animation: "spinner",
    success: function() {
        // your success code here
    }
});

预过滤器将确保在需要时启动和停止“旋转”动画。

当然,这样,您可以安装备选动画并根据请求选择所需的动画。您甚至可以使用ajaxSetup为所有请求设置默认动画:

jQuery.ajaxSetup({
    animation: "spinner"
});

3
你可以在这里设置全局的 ajax 加载图标处理程序,使用 #ajxLoader 来指定你的加载图标。
   $( document ).ajaxStart(function() {
        $("#ajxLoader").fadeIn();
    });

    $( document ).ajaxComplete(function() {
        $("#ajxLoader").fadeOut();
    });

1
这种方法对于我的目的似乎是最简单的,但无法处理多个ajax调用(当第一个完成时就会淡出)。为了解决这个问题,我使用了ajaxStop而不是ajaxComplete。如果您想使用此方法,请参阅文档 - danj1974

3

我发现最好的方法是,假设你正在填充一个当前为空的字段,那么在CSS中定义一个.loading类,并使用background-image: url('images/loading.gif')。然后,您可以使用jQuery根据需要添加和删除加载类。


2
$(function() {
        $('.error').hide();
        $("#checkin-button").click(function() {
                var mid = $("input#mid").val();
                var message = $("textarea#message").val();
                var facebook = $('input#facebook').is(':checked');
                var name = $("input#name").val();
                var bgg_id = $("input#bgg-id").val();
                var thumbnail = $("input#thumbnail").val();
                var dataString = 'mid=' + mid + '&message=' + message + '&facebook=' + facebook + '&name=' + name + '&bgg_id=' + bgg_id + '&thumbnail=' + thumbnail;
                $.ajax({
                        type : "POST",
                        url : "/game-checkin",
                        data : dataString,
                        beforeSend : function() {
                         $('#preloader').addClass('active');
                        },
                        success : function(badges) {
                            $('#preloader').removeClass('active');
                            $('#checkin-form').html("<div id='message'></div><div id='badges'></div>");
                            $('#message').html("<h2><img class=\"check-mark\" src=\"/static/images/check-mark.png\"/>You are checked in!</h2>");
                            $.each(badges, function(i, badge) {
                                    $('#badges').append("<h2>New Badge!</h2><p><img class='badge' src='" + badge.image_url + "'><span class='badge-title'>" + badge.name + "</span></p>");
                                });
                        },
                        complete : function() {
                            $('#preloader').removeClass('active');                      
                        }
                    });
                return false;
            });
    });

#preloader{
 background: url(staticpreloader.gif);
}
.active {
 background: url(activepreloader.gif);
}

2
我曾写过一篇关于如何在通用文档级别上实现此操作的博客文章。文章链接:点击这里
// prepare the form when the DOM is ready 
$(document).ready(function() { 

  // Setup the ajax indicator
  $('body').append('<div id="ajaxBusy"><p><img src="images/loading.gif"></p></div>');

  $('#ajaxBusy').css({
    display:"none",
    margin:"0px",
    paddingLeft:"0px",
    paddingRight:"0px",
    paddingTop:"0px",
    paddingBottom:"0px",
    position:"absolute",
    right:"3px",
    top:"3px",
     width:"auto"
  });
});

// Ajax activity indicator bound to ajax start/stop document events
$(document).ajaxStart(function(){ 
  $('#ajaxBusy').show(); 
}).ajaxStop(function(){ 
  $('#ajaxBusy').hide();
});

2
当你运行$.ajax()方法时,AJAX过程就开始了,直到“complete”回调运行才停止。因此,在$.ajax()代码行之前启动处理的影像/通知,在“完成”回调中结束它。 ajaxStartajaxStop处理程序可以添加到任何元素中,并在每次AJAX请求开始或停止时调用(如果存在并发实例,则仅在第一个实例上调用start,在最后一个实例上调用stop)。因此,如果在页面上有代表任何和所有活动的状态微调器,那么这只是进行全局通知的另一种方式。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接