如何显示jQuery中的加载微调器?


412

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

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

function showLoad () {
    ...
}

jQuery中,我可以使用以下命令将服务器页面加载到元素中:

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

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

Answers:


793

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

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

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

更新:从jQuery 1.8开始,文档规定.ajaxStart/Stop只应附加到document。这会将上面的代码段转换为:

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

48
对于一次简单地加载到DIV中来说,这可能太笼统了。
蒙特利尔,

363
太全球化了?您想要多少个不同的“请稍候”消息?
尼克

23
不幸的是,如果您不想只显示模式加载窗口,而是将其显示在等待加载ajax内容的元素附近,则无法通过这种方式来控制加载div的位置
glaz666 2010年

10
ajaxStart和ajaxStop是jQuery事件,因此您可以为其命名空间:stackoverflow.com/questions/1191485/…docs.jquery.com/Namespaced_Events
David Xia

10
如果使用jQuery> = 1.9,则将ajaxStart和ajaxStop事件附加到$(document)。jquery.com/upgrade-guide/1.9/…–
Domenic,

213

对于jQuery,我使用

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

13
对我有用,该html应该具有以下内容:<div id ='loader'> <img src =“ spinner.gif” /> </ div>
yigal 2012年

7
这对我来说是最干净的。而不是ajaxSetup,我将beforeSend:和complete放在$ ajax({...语句内)
kenswdev 2012年

4
不知道它的价值,但是jQuery在其文档中提到不建议使用.ajaxSetup()链接
pec

注意这里beforeSend在每次调用之前都会被调用,而ajaxStart只有在第一个 ajax方法被调用时才会被触发。同样对于ajaxStop,在最后一个 ajax调用结束时会调用它。如果您有多个并发请求,则此答案中的代码段将无法正常工作。
尼克

如果ajax呼叫超时,则对我不起作用(适用于Mac的Firefox 28)。
osa 2014年

48

您可以只使用jQuery的.ajax函数并使用其选项beforeSend并定义一些函数,在其中可以显示诸如loader div之类的内容,而在成功选项中,您可以隐藏该loader 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();
    }
});

您可以具有任何Spinning Gif图像。这是一个根据您的配色方案是出色的AJAX Loader Generator的网站:http : //ajaxload.info/


16
success如果有错误将不会被调用,而是“你总会收到complete根据回调,甚至是同步请求,” jQuery的阿贾克斯活动
LeeGee 2012年

23

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

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

这样可以确保您的动画在后续请求中从同一帧开始(如果重要)。请注意,旧版本的IE 可能在动画方面存在困难。

祝好运!


13
最重要的提示:在显示设置为none的div中预加载spinner.gif。否则,由于微调器仍在下载,您可能会得到一些微调的延迟效果。
uriDium 2010年

一个不错的提示,比使用别人的插件简单得多
Gordon Thompson

真好!但是,亲爱的,即使页面已经加载,我还要显示2秒微调器。
FM FM

5
@BothFM因为人们喜欢等待事情...?
乔什·斯托多拉

21
$('#message').load('index.php?pg=ajaxFlashcard', null, showResponse);
showLoad();

function showResponse() {
    hideLoad();
    ...
}

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


您在那里可能存在计时问题,不是吗?
TimBüthe2011年

2
@UltimateBrent我认为您错了。为什么showLoad()不是回调?JavaScript将异步加载内容。如果我是对的,那么即使在内容加载之前,showLoad()仍然可以工作。
Jaseem

2
@Jaseem我也使用类似的方法,它实际上依赖于异步调用。我将showLoad放在ajax调用之前的某个位置,但重点是显示一个微调器,让JS启动该调用,并在AJAX完成后在回调中杀死该微调器。
Nenotlep

17

如果您正在使用$.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'
    });  

11

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

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

10
一个用于完成此简单任务的插件?那不是一个很好的解决方案吗?谁想在一个页面上加载100个脚本?
2011年

2
同意 如果需要更好的性能,请压缩并连接。
内森·布巴纳

9
意见不同:如果您希望能够维护您的工作并让其他人也这样做,则将它们分开并模块化,重用代码。您的用户的客户端连接如此差的机会有什么机会不能像您的代码那样加载插件?
LeeGee 2012年

@NathanBubna链接已死
SpringLearner '16

“您的用户的客户端连接如此差的机会有多少不能像您的代码那样加载插件?” 我会说很好。
安德鲁·奥克森伯格

9

变体:我在主页的左上方有一个带有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

最后,我对原始答复进行了两项更改。

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

不错的解决方法。ajaxComplete重试请求时似乎会过早触发,因此我使用了ajaxSend和的组合,ajaxStop效果很好。
Mahn 2014年

@SchweizerSchoggi:还有其他主题可以回答该问题,请使用搜索!
EmilStenström2015年

8

我也想为这个答案做贡献。我一直在寻找与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>

它是如此简单 :)


8

您可以简单地将加载程序映像分配给同一标签,稍后使用Ajax调用在该标签上加载内容:

$("#message").html('<span>Loading...</span>');

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

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


1
这样很难管理UI。对于“加载”文本和最终消息,我们可能需要完全不同的样式。我们可以使用上面提到的回调方法来处理此问题
Jaseem 2011年

6

除了为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;  
}

1
我认为这应该是选定的答案。谢谢@LeeGee。
Nam G VU

真的伟大的答案
尼科夫

4

请注意,必须使用异步调用来使微调器起作用(至少这是导致我的直到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                
        }
    });

4
$('#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与透明背景
伊莎贝拉Skibinska

2

我在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调用完成后替换其内容。


2

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

jQuery的

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

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

咖啡

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

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

文件:ajaxStartajaxStop


是的,如果您愿意,您可以将其与此答案中提到的插件一起使用...
马特

2

的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; }

2

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


非常好!特别是如果您看一下演示,请执行以下操作。禁用DOM元素,在标记中,完全覆盖,元素覆盖...它提供了您需要的一切。你可以很容易地结合全覆盖式与这个答案得到它立即工作。
马特

1

我这样做:

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

1

我想你是对的。此方法过于全局...

但是-当您的AJAX调用对页面本身没有影响时,这是一个很好的默认设置。(例如后台保存)。(您始终可以通过传递“ global”将其关闭以用于某些ajax调用:false-请参阅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);
};


1

如果您打算在每次发出服务器请求时都使用加载程序,则可以使用以下模式。

 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/


1

实际上,我的ajax代码如下所示:我刚刚注释了async:错误的行,并显示了微调框。

$.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,我使用了很棒的字体类:

<i id="ajaxspinner" class="fas fa-spinner fa-spin fa-3x fa-fw" style="display:none"></i>

希望它可以帮助某人。


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.