【问题标题】:Delaying the loading spinner while doing ajax requests in jQuery在 jQuery 中执行 ajax 请求时延迟加载微调器
【发布时间】:2012-03-13 20:33:13
【问题描述】:

在我的 jQuery 代码中执行 AJAX 请求时,我正在使用以下模型来显示我的加载微调器:

jQuery.ajaxSetup({
beforeSend: function() {
    $('#loader').show()
},
complete: function(){
    $('#loader').hide()
},
success: function() {
    $('#loader').hide()
}
});

这段代码对我来说非常好用!

只有一个问题:

有些请求非常简单快速,因此加载微调器仅显示几毫秒。那当然不是很漂亮。

所以我尝试使用setTimeout() 显示加载微调器略有延迟。我希望它仅在 AJAX 请求至少需要 100 毫秒时才会弹出,但它不起作用。

所以我需要一些代码来延迟加载微调器,就像我上面解释的那样,所以它只会在执行“更长”的 AJAX 请求时弹出!

【问题讨论】:

  • 当您说“但它不起作用”时,什么不起作用?你能告诉我们你试过的代码吗?
  • 另外...在!:)thx 上放轻松。我的眼睛受伤了。

标签: jquery ajax


【解决方案1】:

这就是我解决您提到的功能的方式

    var loading;
    $("#loader").hide();
    jQuery.ajaxSetup({
        beforeSend: function() {
             loading= setTimeout("$('#loader').show()", 300);
        },
        complete: function(){
             clearTimeout(loading);
             $("#loader").hide();   
        },
        success: function() {
             alert("done");
        }
    });

【讨论】:

  • 如果请求需要 301 毫秒才能完成,这将出现同样的问题。除了更糟糕的是,因为现在用户必须等待一段时间才能显示任何明显的事情。
  • 我想有点偏好。如果你不知道你的请求需要多长时间,我认为更安全的说法是:坚持显示加载程序,直到请求超过快速加载阈值
  • 不能 100% 工作! :( 问题是现在加载微调器在第一次加载页面时也会显示并且之后不会消失。我尝试使用 $('#loader').hide() @ document.ready 但加载后仍然没有消失页面成功!
  • 如果您有多个并行 AJAX 调用,这将不起作用,对吧?您知道如何最好地规避这种情况吗?
  • 对于许多 ajax 请求/回调,我可能会使用 jQuery.Deferred() api.jquery.com/category/deferred-object 来管理它们
【解决方案2】:

这是一个老问题,但我发现了一种更好、更优雅的方法。 jQuery 公开了一个变量$.active,它是当前活动的 ajax 请求的数量。此值在ajaxSend 之前增加,在ajaxComplete 之后减少。

考虑到这一点,我们需要做的就是在触发ajaxSend$.active == '1' 时显示微调器,并在触发ajaxComplete$.active == '1' 时隐藏微调器。这是我目前完美运行的代码。

$(document).ajaxSend(function(event, request, settings) {
    $.active == '1' ? $('#spinner').show() : '';
});

$(document).ajaxComplete(function(event, request, settings) {
    $.active == '1' ? $('#spinner').hide() : '';
});

希望这对某人有所帮助。

【讨论】:

    【解决方案3】:

    我见过的常见解决方案是让颤动者保持一两秒钟,即使请求完成得比这更快。比如:

    var loaded = false;
    var throbbed = false;
    
    function checkComplete(){
        if(loaded && throbbed){
            $("#loader").hide();
        }
    }
    
    function requestComplete(){
        loaded = true;
        checkComplete();
    }
    
    jQuery.ajaxSetup({
    beforeSend: function() {
        $('#loader').show();
        setTimeout(function(){
            throbbed = true;
            checkComplete();
        }, 500);
    
    },
    complete: requestComplete,
    success: requestComplete
    });
    

    显然,这需要以牺牲美观为代价来让事情变慢,因此您是否愿意接受这种打击取决于具体情况。如果它是一直被使用的东西,那么你最好接受丑陋的东西。如果它每隔一段时间就会发生一次,用户不会注意到额外的 500 mils。

    【讨论】:

      【解决方案4】:

      这应该可行:

      var timeout;
      
      jQuery.ajaxSetup({
      beforeSend: function() {
          timeout = window.setTimeout(function() {
              timeout = null;
              $('#loader').show();
          }, 100);
      },
      complete: function(){
          if (timeout) {
              window.clearTimeout(timeout);
              timeout = null;
          }
          $('#loader').hide()
      },
      success: function() {
          // No need to do anything here since complete always will be called
      }
      });
      

      现在,如果您同时发出多个请求,则需要稍微改进一下,但希望您能明白这一点。

      【讨论】:

      • 不能 100% 工作! :( 问题是现在加载微调器在第一次加载页面时也会显示并且之后不会消失。我尝试使用 $('#loader').hide() @ document.ready 但加载后仍然没有消失页面成功!
      【解决方案5】:

      现在回复,因为我遇到了同样的问题,这些答案给了我部分解决方案。 为了避免在 ajax 请求完成后启动微调器,因为超时时间比执行脚本更宽,您需要检查 up/down 标志,这非常简单并且对我有用。

      var m = $('.modal-ajax');
      var run = false; // global scope is necessary
      m.hide(); // if isn't hidden in css
      
      jQuery.ajaxSetup({
          beforeSend: function() {
              run = true; // up flag          
              d = setTimeout(function(){
                  if(run) // is ajax executing now?
                      m.show();
              },100); // is trigged only for NO fast response
          },
          complete: function(){
              m.hide();
              run = false; // down flag                
          },
          success: function() {            
        //  do stuff
          }
      });
      

      【讨论】:

        猜你喜欢
        • 2014-03-15
        • 1970-01-01
        • 2023-03-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-12-01
        相关资源
        最近更新 更多