【问题标题】:How to show loading spinner in jQuery?如何在 jQuery 中显示加载微调器?
【发布时间】:2010-09-09 06:28:01
【问题描述】:

Prototype 中,我可以使用以下代码显示“正在加载...”图像:

var myAjax = new Ajax.Request( url, {method: 'get', parameters: pars, 
onLoading: showLoad, onComplete: showResponse} );

function showLoad () {
    ...
}

jQuery 中,我可以将服务器页面加载到一个元素中:

$('#message').load('index.php?pg=ajaxFlashcard');

但是如何像在 Prototype 中那样将加载微调器附加到此命令?

【问题讨论】:

    标签: jquery spinner prototypejs equivalence language-interoperability


    【解决方案1】:

    有几种方法。我首选的方法是将函数附加到元素本身的 ajaxStart/Stop 事件。

    $('#loadingDiv')
        .hide()  // Hide it initially
        .ajaxStart(function() {
            $(this).show();
        })
        .ajaxStop(function() {
            $(this).hide();
        })
    ;
    

    每当您执行任何 Ajax 调用时,ajaxStart/Stop 函数都会触发。

    更新:从 jQuery 1.8 开始,文档声明 .ajaxStart/Stop 只能附加到 document。这会将上面的 sn-p 转换为:

    var $loading = $('#loadingDiv').hide();
    $(document)
      .ajaxStart(function () {
        $loading.show();
      })
      .ajaxStop(function () {
        $loading.hide();
      });
    

    【讨论】:

    • 对于一个简单的 DIV 加载来说,这可能过于全局了。
    • 过于全球化?你想要多少不同的“请稍候”消息?
    • 不幸的是,这种方式无法控制加载 div 的位置,以防您不想只显示模式加载窗口,而是在等待加载 ajax 内容的元素附近显示它。 .
    • ajaxStart 和 ajaxStop 是 jQuery 事件,因此您可以命名它们:stackoverflow.com/questions/1191485/…docs.jquery.com/Namespaced_Events
    • 如果使用 jQuery >= 1.9,请将 ajaxStart 和 ajaxStop 事件附加到 $(document)。 jquery.com/upgrade-guide/1.9/…
    【解决方案2】:

    对于 jQuery 我使用

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

    【讨论】:

    • 对我有用,html 应该有类似的内容:
    • 这个对我来说是最干净的。我没有使用 ajaxSetup,而是将 beforeSend: 和 complete: 放在 $ajax({... 语句中。
    • 不知道它的价值,但 jQuery 在其文档中提到不推荐使用 .ajaxSetup()link
    • 注意这里beforeSend在每次调用之前都会被调用,而ajaxStart只有在调用first ajax方法时才会触发。同样对于ajaxStop,它在last ajax 调用完成时被调用。如果您有多个并发请求,则此答案中的 sn-p 将无法正常工作。
    • 如果 ajax 调用超时(Firefox 28 for Mac)对我不起作用。
    【解决方案3】:

    您可以只使用 jQuery 的 .ajax 函数并使用其选项 beforeSend 并定义一些函数,您可以在其中显示类似加载器 div 的内容,并且在成功选项中您可以隐藏该加载器 div。

    jQuery.ajax({
        type: "POST",
        url: 'YOU_URL_TO_WHICH_DATA_SEND',
        data:'YOUR_DATA_TO_SEND',
        beforeSend: function() {
            $("#loaderDiv").show();
        },
        success: function(data) {
            $("#loaderDiv").hide();
        }
    });
    

    您可以拥有任何旋转的 Gif 图像。根据您的配色方案,这是一个很棒的 AJAX 加载器生成器网站:http://ajaxload.info/

    【讨论】:

    • 如果出现错误,success 将不会被调用,但是根据jQuery Ajax Events 的说法,“即使对于同步请求,您也将始终收到 complete 回调”。
    【解决方案4】:

    您可以在 AJAX 调用之前将动画图像插入 DOM,并执行内联函数将其删除...

    $("#myDiv").html('<img src="images/spinner.gif" alt="Wait" />');
    $('#message').load('index.php?pg=ajaxFlashcard', null, function() {
      $("#myDiv").html('');
    });
    

    这将确保您的动画在后续请求中从同一帧开始(如果这很重要)。请注意,旧版本的 IE可能在动画方面有问题。

    祝你好运!

    【讨论】:

    • 重要提示:在显示设置为无的 div 中预加载 spinner.gif。否则,由于微调器仍在下载,您可能会得到一些延迟微调器效果。
    • 不错的技巧,比使用别人的插件简单得多
    • 不错!但是亲爱的,即使页面已经加载,我还想显示微调器 2 秒。
    • @BothFM 因为人们喜欢等待……?
    【解决方案5】:

    如果你使用$.ajax(),你可以使用这样的东西:

    $.ajax({
      url: "destination url",
      success: sdialog,
      error: edialog,
      // shows the loader element before sending.
      beforeSend: function() {
        $("#imgSpinner1").show();
      },
      // hides the loader after completion of request, whether successfull or failor.             
      complete: function() {
        $("#imgSpinner1").hide();
      },
      type: 'POST',
      dataType: 'json'
    });
    

    虽然设置名为“beforeSend”,但从jQuery 1.5 "beforeSend" will be called regardless of the request type. 开始,即.show() 函数将在type: 'GET' 时被调用。

    【讨论】:

      【解决方案6】:
      $('#message').load('index.php?pg=ajaxFlashcard', null, showResponse);
      showLoad();
      
      function showResponse() {
          hideLoad();
          ...
      }
      

      http://docs.jquery.com/Ajax/load#urldatacallback

      【讨论】:

      • 你可能有时间问题,不是吗?
      • @UltimateBrent 我认为你弄错了。为什么 showLoad() 不是回调? JavaScript 将异步加载内容。如果我是正确的,showLoad() 甚至可以在内容加载之前工作。
      • @Jaseem 我也使用了类似的方法,它实际上依赖于异步调用。我会将 showLoad 放在 ajax 调用之前的某个地方,但重点是显示一个微调器,让 JS 启动调用,并在 AJAX 完成后在回调中终止微调器。
      【解决方案7】:

      使用加载插件:http://plugins.jquery.com/project/loading

      $.loading.onAjax({img:'loading.gif'});
      

      【讨论】:

      • 这个简单任务的插件?这不是一个很好的解决方案是吗?谁想在一个页面上加载 100 个脚本?
      • 同意。如果您想要更好的性能,请压缩和连接。
      • 不同意:分离和模块化,重用代码,如果您希望能够维护您的工作并让其他人也这样做。您的用户连接如此糟糕,他们的客户端无法加载插件以及您的代码的可能性有多大?
      • @NathanBubna 链接已失效
      • “你的用户有什么机会连接如此糟糕,他们的客户端无法加载插件以及你的代码?”我会说很好。
      【解决方案8】:

      变体:我在主页的左上角有一个带有 id="logo" 的图标;当 ajax 工作时,一个微调器 gif 会覆盖在顶部(具有透明度)。

      jQuery.ajaxSetup({
        beforeSend: function() {
           $('#logo').css('background', 'url(images/ajax-loader.gif) no-repeat')
        },
        complete: function(){
           $('#logo').css('background', 'none')
        },
        success: function() {}
      });
      

      【讨论】:

        【解决方案9】:

        我最终对original reply 进行了两次更改。

        1. 从 jQuery 1.8 开始,ajaxStart 和 ajaxStop 只能附加到 document。这使得仅过滤一些 ajax 请求变得更加困难。苏...
        2. 切换到ajaxSendajaxComplete 可以在显示微调器之前检查当前的ajax 请求。

        这是更改后的代码:

        $(document)
            .hide()  // hide it initially
            .ajaxSend(function(event, jqxhr, settings) {
                if (settings.url !== "ajax/request.php") return;
                $(".spinner").show();
            })
            .ajaxComplete(function(event, jqxhr, settings) {
                if (settings.url !== "ajax/request.php") return;
                $(".spinner").hide();
            })
        

        【讨论】:

          【解决方案10】:

          我也想为这个答案做出贡献。我一直在 jQuery 中寻找类似的东西,而这正是我最终使用的东西。

          我从http://ajaxload.info/ 获得了加载微调器。我的解决方案基于http://christierney.com/2011/03/23/global-ajax-loading-spinners/ 的这个简单答案。

          基本上你的 HTML 标记和 CSS 应该是这样的:

          <style>
               #ajaxSpinnerImage {
                    display: none;
               }
          </style>
          
          <div id="ajaxSpinnerContainer">
               <img src="~/Content/ajax-loader.gif" id="ajaxSpinnerImage" title="working..." />
          </div>
          

          然后你的 jQuery 代码看起来像这样:

          <script>
               $(document).ready(function () {
                    $(document)
                    .ajaxStart(function () {
                         $("#ajaxSpinnerImage").show();
                    })
                    .ajaxStop(function () {
                         $("#ajaxSpinnerImage").hide();
                    });
          
                    var owmAPI = "http://api.openweathermap.org/data/2.5/weather?q=London,uk&APPID=YourAppID";
                    $.getJSON(owmAPI)
                    .done(function (data) {
                         alert(data.coord.lon);
                    })
                    .fail(function () {
                         alert('error');
                    });
               });
          </script>
          

          就这么简单:)

          【讨论】:

            【解决方案11】:

            您可以简单地将加载器图像分配给稍后将使用 Ajax 调用加载内容的同一标签:

            $("#message").html('<span>Loading...</span>');
            
            $('#message').load('index.php?pg=ajaxFlashcard');
            

            您也可以将 span 标签替换为图像标签。

            【讨论】:

            • 这样管理 UI 会很困难。对于“加载”文本和最终消息,我们可能需要完全不同的样式。我们可以使用上面提到的回调方法来处理这个问题
            【解决方案12】:

            除了为 ajax 事件设置全局默认值外,您还可以为特定元素设置行为。也许仅仅改变他们的班级就足够了?

            $('#myForm').ajaxSend( function() {
                $(this).addClass('loading');
            });
            $('#myForm').ajaxComplete( function(){
                $(this).removeClass('loading');
            });
            

            示例 CSS,使用微调器隐藏 #myForm:

            .loading {
                display: block;
                background: url(spinner.gif) no-repeat center middle;
                width: 124px;
                height: 124px;
                margin: 0 auto;
            }
            /* Hide all the children of the 'loading' element */
            .loading * {
                display: none;  
            }
            

            【讨论】:

              【解决方案13】:

              请注意,您必须使用异步调用才能使微调器工作(至少这是导致我的直到 ajax 调用之后才显示,然后在调用完成并移除微调器后迅速消失的原因)。

              $.ajax({
                      url: requestUrl,
                      data: data,
                      dataType: 'JSON',
                      processData: false,
                      type: requestMethod,
                      async: true,                         <<<<<<------ set async to true
                      accepts: 'application/json',
                      contentType: 'application/json',
                      success: function (restResponse) {
                          // something here
                      },
                      error: function (restResponse) {
                          // something here                
                      }
                  });
              

              【讨论】:

                【解决方案14】:
                $('#loading-image').html('<img src="/images/ajax-loader.gif"> Sending...');
                
                        $.ajax({
                            url:  uri,
                            cache: false,
                            success: function(){
                                $('#loading-image').html('');           
                            },
                
                           error:   function(jqXHR, textStatus, errorThrown) {
                            var text =  "Error has occured when submitting the job: "+jqXHR.status+ " Contact IT dept";
                           $('#loading-image').html('<span style="color:red">'+text +'  </span>');
                
                            }
                        });
                

                【讨论】:

                • 最短的方法是插入带有透明背景的从ajaxload.info 下载的图像的图像标签
                【解决方案15】:

                我在 jQuery UI 对话框中使用了以下内容。 (也许它适用于其他 ajax 回调?)

                $('<div><img src="/i/loading.gif" id="loading" /></div>').load('/ajax.html').dialog({
                    height: 300,
                    width: 600,
                    title: 'Wait for it...'
                });
                

                包含一个动画加载 gif,直到 ajax 调用完成后其内容被替换。

                【讨论】:

                  【解决方案16】:

                  这对我来说是最好的方式:

                  jQuery

                  $(document).ajaxStart(function() {
                    $(".loading").show();
                  });
                  
                  $(document).ajaxStop(function() {
                    $(".loading").hide();
                  });
                  

                  咖啡

                    $(document).ajaxStart ->
                      $(".loading").show()
                  
                    $(document).ajaxStop ->
                      $(".loading").hide()
                  

                  文档:ajaxStartajaxStop

                  【讨论】:

                    【解决方案17】:

                    JavaScript

                    $.listen('click', '#captcha', function() {
                        $('#captcha-block').html('<div id="loading" style="width: 70px; height: 40px; display: inline-block;" />');
                        $.get("/captcha/new", null, function(data) {
                            $('#captcha-block').html(data);
                        }); 
                        return false;
                    });
                    

                    CSS

                    #loading { background: url(/image/loading.gif) no-repeat center; }
                    

                    【讨论】:

                      【解决方案18】:

                      这是一个非常简单和智能的插件用于特定目的: https://github.com/hekigan/is-loading

                      【讨论】:

                      • 真的很好!特别是如果您查看演示...禁用 DOM 元素、标签内、完全覆盖、元素覆盖...它提供了您需要的一切。您可以轻松地将 Full Overlay 与 this answer 结合使用,使其立即工作。
                      【解决方案19】:

                      我这样做:

                      var preloaderdiv = '<div class="thumbs_preloader">Loading...</div>';
                                 $('#detail_thumbnails').html(preloaderdiv);
                                   $.ajax({
                                              async:true,
                                              url:'./Ajaxification/getRandomUser?top='+ $(sender).css('top') +'&lef='+ $(sender).css('left'),
                                              success:function(data){
                                                  $('#detail_thumbnails').html(data);
                                              }
                                   });
                      

                      【讨论】:

                        【解决方案20】:

                        我认为你是对的。 这个方法太全球化了……

                        但是 - 当您的 AJAX 调用对页面本身没有影响时,这是一个很好的默认值。 (例如背景保存)。 (您总是可以通过传递 "global":false 为某个 ajax 调用关闭它 - 请参阅jquery 的文档

                        当 AJAX 调用旨在刷新页面的一部分时,我喜欢我的“加载”图像特定于刷新的部分。我想看看哪个部分被刷新了。

                        想象一下,如果你能简单地写出这样的东西会多么酷:

                        $("#component_to_refresh").ajax( { ... } ); 
                        

                        这将在此部分显示“正在加载”。 下面是我编写的一个函数,它也处理“加载”显示,但它特定于您在 ajax 中刷新的区域。

                        首先,让我告诉你如何使用它

                        <!-- assume you have this HTML and you would like to refresh 
                              it / load the content with ajax -->
                        
                        <span id="email" name="name" class="ajax-loading">
                        </span>
                        
                        <!-- then you have the following javascript --> 
                        
                        $(document).ready(function(){
                             $("#email").ajax({'url':"/my/url", load:true, global:false});
                         })
                        

                        这就是功能 - 一个基本的开始,您可以根据需要进行增强。它非常灵活。

                        jQuery.fn.ajax = function(options)
                        {
                            var $this = $(this);
                            debugger;
                            function invokeFunc(func, arguments)
                            {
                                if ( typeof(func) == "function")
                                {
                                    func( arguments ) ;
                                }
                            }
                        
                            function _think( obj, think )
                            {
                                if ( think )
                                {
                                    obj.html('<div class="loading" style="background: url(/public/images/loading_1.gif) no-repeat; display:inline-block; width:70px; height:30px; padding-left:25px;"> Loading ... </div>');
                                }
                                else
                                {
                                    obj.find(".loading").hide();
                                }
                            }
                        
                            function makeMeThink( think )
                            {
                                if ( $this.is(".ajax-loading") )
                                {
                                    _think($this,think);
                                }
                                else
                                {
                                    _think($this, think);
                                }
                            }
                        
                            options = $.extend({}, options); // make options not null - ridiculous, but still.
                            // read more about ajax events
                            var newoptions = $.extend({
                                beforeSend: function()
                                {
                                    invokeFunc(options.beforeSend, null);
                                    makeMeThink(true);
                                },
                        
                                complete: function()
                                {
                                    invokeFunc(options.complete);
                                    makeMeThink(false);
                                },
                                success:function(result)
                                {
                                    invokeFunc(options.success);
                                    if ( options.load )
                                    {
                                        $this.html(result);
                                    }
                                }
                        
                            }, options);
                        
                            $.ajax(newoptions);
                        };
                        

                        【讨论】:

                          【解决方案21】:

                          如果您不想编写自己的代码,也有很多插件可以做到这一点:

                          【讨论】:

                            【解决方案22】:

                            如果您计划每次发出服务器请求时都使用加载器,则可以使用以下模式。

                             jTarget.ajaxloader(); // (re)start the loader
                             $.post('/libs/jajaxloader/demo/service/service.php', function (content) {
                                 jTarget.append(content); // or do something with the content
                             })
                             .always(function () {
                                 jTarget.ajaxloader("stop");
                             });
                            

                            这段代码特别使用了jajaxloader插件(我刚刚创建)

                            https://github.com/lingtalfi/JAjaxLoader/

                            【讨论】:

                              【解决方案23】:

                              我的 ajax 代码看起来像这样,实际上,我刚刚注释掉了 async: false 行并且微调器出现了。

                              $.ajax({
                                      url: "@Url.Action("MyJsonAction", "Home")",
                                      type: "POST",
                                      dataType: "json",
                                      data: {parameter:variable},
                                      //async: false, 
                              
                                      error: function () {
                                      },
                              
                                      success: function (data) {
                                        if (Object.keys(data).length > 0) {
                                        //use data 
                                        }
                                        $('#ajaxspinner').hide();
                                      }
                                    });
                              

                              我在 ajax 代码之前的函数中显示微调器:

                              $("#MyDropDownID").change(function () {
                                      $('#ajaxspinner').show();
                              

                              对于 Html,我使用了一个很棒的字体类:

                              &lt;i id="ajaxspinner" class="fas fa-spinner fa-spin fa-3x fa-fw" style="display:none"&gt;&lt;/i&gt;

                              希望对某人有所帮助。

                              【讨论】:

                              • 但您也需要在出错时隐藏微调器。
                              【解决方案24】:

                              您始终可以使用Block UI jQuery plugin,它会为您完成所有工作,它甚至会在加载 ajax 时阻止任何输入的页面。如果该插件似乎无法正常工作,您可以阅读有关使用它的正确方法in this answer. 看看。

                              【讨论】:

                                猜你喜欢
                                • 1970-01-01
                                • 2021-12-05
                                • 1970-01-01
                                • 2011-11-04
                                • 1970-01-01
                                • 1970-01-01
                                • 1970-01-01
                                • 1970-01-01
                                • 1970-01-01
                                相关资源
                                最近更新 更多