为啥我的微调器 GIF 在运行 jQuery ajax 调用时停止?

Posted

技术标签:

【中文标题】为啥我的微调器 GIF 在运行 jQuery ajax 调用时停止?【英文标题】:Why does my spinner GIF stop while jQuery ajax call is running?为什么我的微调器 GIF 在运行 jQuery ajax 调用时停止? 【发布时间】:2008-10-10 14:01:21 【问题描述】:

我刚刚开始摆脱 ASP.NET UpdatePanels。我正在使用 jQuery 和 jTemplates 将 Web 服务的结果绑定到网格,并且一切正常。

事情是这样的:我试图在刷新表格时显示一个微调器 GIF(在 ASP.NET 中的更新进度)我已经完成了所有工作,除了微调器被冻结。为了查看发生了什么,我尝试将微调器从更新进度 div 中移出,并移到我可以一直看到的页面上。它不停地旋转直到刷新开始,并保持冻结状态直到刷新完成,然后再次开始旋转。 “请稍候”微调器并不是您真正想要的!

这是在 IE7 中 - 还没有机会在其他浏览器中进行测试。有什么想法吗? ajax 调用或客户端数据绑定是否占用大量资源,以至于浏览器无法处理其动画 GIF?

更新

这是刷新网格的代码。不确定这是同步的还是异步的。

updateConcessions = function(e) 
    $.ajax(
        type: "POST",
        url: "Concessions.aspx/GetConcessions",
        data: "'Countries':'ga'",
        contentType: "application/json; charset=utf-8",
        dataType: "json",
        success: function(msg) 
            applyTemplate(msg);
        ,
        error: function(XMLHttpRequest, textStatus, errorThrown) 
        
    );


applyTemplate = function(msg) 
    $('div#TemplateTarget').setTemplate($('div#TemplateSource').html());
    $('div#TemplateTarget').processTemplate(msg);

更新 2

我刚刚检查了jQuery documentation,$.ajax() 方法默认是异步的。只是为了好玩,我添加了这个

$.ajax(
    async: true,
    ...

它没有任何区别。

【问题讨论】:

显示微调器的呼叫何时发生? 您是否在 IE 的设置中禁用了动画? 这可能会帮助像我一样一直在搜索的人:***.com/questions/7440897/… 更好的解决方案fgnass.github.io/spin.js 【参考方案1】:

冻结浏览器的不是 Ajax 调用。它是成功处理程序(applyTemplate)。将 HTML 插入这样的文档会冻结 IE,具体取决于 HTML 的数量。这是因为 IE UI 是单线程的;如果您注意到,实际的 IE 菜单在发生这种情况时也会被冻结。

作为测试,试试:

applyTemplate = function(msg) 
   return;

【讨论】:

您说得对,先生。我想我需要 (a) 接受它或 (b) 找到更高效的模板引擎。 more efficient BROWSER 更喜欢它! 这似乎在 Chrome 中发生在我身上?!? 这也发生在我身上,但我的 GIF 文件在除 Opera 之外的所有浏览器中停止动画。我用 IE9、FF、Chrome、Opera 和 Safari 进行了测试。在 Opera 中,GIF 文件是动画的,但速度很慢。我的猜测是 Opera 正在腾出一些时间来重绘屏幕。但是对于所有其他浏览器,当我为响应 AJAX 调用而将 HTML 渲染和爆破到容器中时,GIF 文件完全被锁定。我知道人们倾向于将一切都归咎于 IE,但在这种情况下,IE 的行为与 FF、Chrome 和 Safari 相同。 这是我找到的最佳答案:***.com/questions/7440897/…【参考方案2】:

我不记得究竟是什么原因造成的,但我们在 IE6 中遇到了类似的问题,我们在 javascript 中用这个令人难以置信的 hack 修复了它:

setTimeout("document.images['BusyImage'].src=document.images['BusyImage'].src",10);

这只是将图像源设置为之前的样子,但显然足以让 IE 摆脱它的昏迷状态。

编辑:我想我记得是什么原因造成的:我们将动画加载到一个带有 display: none 的 div 中。 IE 加载它并且不启动动画,因为它是隐藏的。不幸的是,当您将包含块设置为 display: 块时它不会启动动画,因此我们使用上面的代码行来欺骗 IE 重新加载图像。

【讨论】:

我也记得类似的东西。 什么时候设置这个超时时间? (我在原始回复中添加了一些细节,但我会在这里详细说明)。在我们将图像的包含块设置为 display:block 后调用 settimeout() 行。【参考方案3】:

图像冻结是因为当它被隐藏时动画被 IE 禁用。

要解决此问题,请附加加载图像而不是取消隐藏它:

function showLoader(callback)
    $('#wherever').append(
        '<img class="waiting" src="/path/to/gif.gif" />'
    );

    callback();


function finishForm()
    var passed = formValidate(document.forms.clientSupportReq);

    if(passed)
    
        $('input#subm')
            .val('Uploading...')
            .attr('disabled','disabled');
        $('input#res').hide();
    

    return passed;

$(function()
    // on submit
    $('form#formid').submit(function()
        var l = showLoader( function()
                         finishForm() 
                    );

        if(!l)
            $('.waiting').remove();
        

        return l;
    );
);

【讨论】:

【参考方案4】:

您确定在 AJAX 调用期间 GIF 没有旋转吗?

在您的让步.aspx 中将此行放在处理 GetConcessions 的某处:-

System.Threading.Thread.Sleep(5000);

我怀疑 gif 会旋转 5 秒,然后在 IE 渲染和绘制结果时冻结。

【讨论】:

【参考方案5】:

我知道问题是关于异步 ajax 调用。但是我想补充一点,我在关于同步 ajax 调用的测试中发现了以下内容:

用于同步 ajax 调用。通话进行时(即等待服务器响应)。对于测试,我在服务器上延迟了服务器响应。

Firefox 17.0.1 - 动画 gif 继续正确动画。

Chrome v23 - 动画 gif 在请求进行时停止动画。

【讨论】:

IE 测试显示结果类似于 Chrome - 我能够将调用更改为异步,但这可能对其他人没有帮助【参考方案6】:

嗯,这有很多原因。首先,当服务器的ajax回调时,你会感觉到你的gif冻结了几毫秒,但相关的并不多。在您开始处理信息之后,根据您操作的对象和操作方式,您将有更多或更少的时间冻结您的 gif。这是因为线程正忙于处理信息。例如,如果您有 1000 个对象并且您执行订单和移动信息,并且您还使用 jquery 和 append、insert、$.each 命令,您会感觉到 gif 冻结。有时不可能避免所有冻结的 gif,但你可以将时间限制在几毫秒这样做:制作一个响应 ajax 列表,每 2 秒处理一次(这样你将在一个单独的数组中得到结果,你会用一个 setInterval 调用它,当之前的响应仍在处理时,您可以避免尝试处理一个响应的瓶颈)。如果您使用 JQuery,请不要使用 $.each,请使用 for。不要使用 dom 操作(追加、插入等),使用 html()。在简历中做更少的代码、重构和处理所有响应(如果你做了更多的 1),就像只有 1 一样。对不起我的英语。

【讨论】:

【参考方案7】:

我遇到了类似的浏览器冻结问题。如果您在本地开发和测试,由于某种原因它会冻结 Web 浏览器。将我的代码上传到 Web 服务器后,它开始工作。我希望这会有所帮助,因为我自己花了好几个小时才弄清楚。

【讨论】:

我使用的是 IE11,这正是我所看到的行为。【参考方案8】:

你是同步调用还是异步调用?同步调用确实会导致浏览器在调用期间看似锁定。另一种可能性是系统正忙于做它正在做的任何工作。

【讨论】:

【参考方案9】:

我过去在进行 AJAX 调用时看到过这种行为。我相信这与浏览器只是单线程的事实有关,因此当返回 AJAX 调用时,线程正在处理调用,因此动画 GIF 需要暂时停止。

【讨论】:

我怀疑这是浏览器架构不可避免的后果 - 在 ASP.NET 中使用 UpdatePanel/UpdateProgress 控件时(这会导致幕后的 ajax 调用),动画 GIF 可以正常工作。跨度> 它认为您会发现 GIF 动画发生在与运行 Javascript 的线程不同的线程上。我的猜测是暂停发生在代码内部为 innerHTML 分配新内容的某个点上。 【参考方案10】:

dennismonsewicz 的回答很好。使用 spin.js,网站http://fgnass.github.com/spin.js/ 显示了非常简单的步骤。 在繁重的过程中,我们应该使用 CSS 动画。 由于单线程限制,不应使用 JS 驱动的动画和 GIF,否则动画将冻结。 CSS 动画与 UI 线程分离。

【讨论】:

【参考方案11】:

setTimeout 函数中包装 ajax 调用帮助我防止 gif 动画冻结:

setTimeout(function() 
    $.get('/some_link', function (response) 
        // some actions
    );
, 0);

【讨论】:

【参考方案12】:

浏览器分为单线程和多线程。

对于任何浏览器: 当你调用一个包含嵌套 ajax 函数的函数时

java/servlet/jsp/控制器 > 保持 Thread.sleep(5000);在 servlet 中了解 ajax 中的 async 时 真假。

    function ajaxFn()
    $('#status').html('WAIT... <img id="theImg" src="page-loader.gif"   />');
    $('#status').css("color","red");
    $.ajax(
        url:"MyServlet",
        method: "POST",
        data:  name: $("textarea").val(),
                id : $("input[type=text]").val() ,
        //async: false,
        success:function(response)
            //alert(response);  //response is "welcome to.."
            $("#status").text(response);
            $('#status').css("color","green");
        ,
        complete:function(x,y)
            //alert(y)
        ,
        error:function()
            $("#status").text("?");
        
    );

 

【讨论】:

以上是关于为啥我的微调器 GIF 在运行 jQuery ajax 调用时停止?的主要内容,如果未能解决你的问题,请参考以下文章

带有加载微调器的 jQuery 验证

使用微调器加载 jQuery 整个 HTML 页面

在 AngularJS 中的 $http 请求期间显示微调器 GIF?

为啥我的搜索栏随着微调器移动?

将微调器 gif 添加/删除到无限滚动?

为啥我在这里得到微调器的空引用错误? [复制]