力UI重新绘制在WebKit的(Safari浏览器和放大器; Chrome浏览器)同步&QUOT前右;阿贾克斯"请求 [英] Force UI repaint in Webkit (Safari & Chrome) right before Synchronous "Ajax" request

查看:149
本文介绍了力UI重新绘制在WebKit的(Safari浏览器和放大器; Chrome浏览器)同步&QUOT前右;阿贾克斯"请求的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在一个简单的基于Ajax的网站,我们是同步做一些Htt的prequests请求(我知道同步的Ajax是一个矛盾的有点)。主要的原因这么做是同步与异步方式是为了简化编程模型,其中一些涉及(长的故事)。

In a simple Ajax based website we are making some HttpRequests requests synchronously (I realize "synchronous Ajax" is somewhat of an oxymoron). The primary reason this is being done synchronously vs. asynchronously is in order to simplify the programming model for some of those involved (long story).

总之,我们希望能够做出造型的变化(特别是覆盖有半透明的白色屏幕为谷歌搜索一样)提出要求的权利面前,然后把它拿走,当结果回来。本质上,这看起来像:

Anyway, we want to be able to make a styling change (specifically, overlay the screen with semi transparent white as Google search does) right before the request is made, and then take it away when results come back. Essentially this looks like:

load:function(url) {
    ....
    busyMask.className="Shown"; //display=block; absolute positioned full screen semi-transparent
    var dta=$.ajax({type:"GET",dataType:"json",url:url,async: false}).responseText;
    busyMask.className="Hidden"; //sets display=none;
    ...
    return JSON.parse(dta);
    }

是公知的同步请求将锁定用户界面。所以毫不奇怪,白色覆盖从来没有出现在Safari和Chrome(它在Firefox中有趣)。我已经试过了响应的方式放慢,并用粉红色的叠加,使这将是非常明显的,但它只是不会更新UI后才请求完成。离开'busyMask.className =隐藏'出一部分将显示mask--但只有在Ajax请求结束。

It is well known a synchronous requests will lock the UI. So not surprisingly, the white overlay never shows up in Safari and Chrome (it does in Firefox interestingly). I've tried slowing the response way down and using a pink overlay so that it will be painfully obvious, but it just won't update the UI until after the request is complete. Leaving the 'busyMask.className="Hidden"' part out will show the mask-- but only after the ajax request is complete.

我看过很多很多技巧迫使用户界面重绘(如<一个href="http://stackoverflow.com/questions/924681/why-hourglass-not-working-with-synchronous-ajax-request-in-google-chrome">Why沙漏工作不与谷歌浏览器同步AJAX请求?,<一个href="http://ajaxian.com/archives/forcing-a-ui-redraw-from-javascript">http://ajaxian.com/archives/forcing-a-ui-redraw-from-javascript),但他们似乎都结合试图展示实际的永久DOM或样式的更新,不与暂时显示,同时同步的请求是由一个风格上的变化。

I've seen many many tricks for forcing the UI to repaint (e.g. Why HourGlass not working with synchronous AJAX request in Google Chrome?, http://ajaxian.com/archives/forcing-a-ui-redraw-from-javascript), but they all seem to be in conjunction with trying to show actual "permanent" DOM or styling updates, not with temporarily showing a style change while a synchronous request is made.

那么,有没有办法做到这一点还是我打一场必败之仗?这可能是因为我们只需要逐个切换到对案件异步请求,为表现最差的请求,这可能是一个体面的方式来解决这个学习曲线的问题......但我希望有一个外盒子回答这里。

So is there a way to do this or am I fighting a losing battle? It may be that we'll just need to switch to asynchronous requests on a case by case basis for the worst performing requests, which might be a decent way to tackle the learning curve issue... But I'm hoping there is an outside the box answer here.

推荐答案

确定对于这个问题,我会忽略的理由,为什么你需要同步XHR请求的目的。我明白,有时候工作的限制不允许使用的最佳实践解决方案,所以我们才能把工作做好凑合。所以让我们专注于如何获得同步Ajax和视觉更新的工作适合你!

Ok for the purpose of this question I will ignore the justification for why you require synchronous XHR requests. I understand that sometimes work constraints don't allow the use of the best practice solution and so we "make do" in order to get the job done. So lets focus on how to get synchronous ajax with visual updated working for you!

那么你正在使用jQuery为您XHR请求考虑,我将承担其确定使用jQuery来显示/隐藏负载指示,并处理任何时间的问题。

Well considering you are using jQuery for your XHR request, I'm going to assume its ok to use jQuery to show/hide the loading indicator and to handle any timing issues.

首先,我们建立了我们的标记加载指示灯:

First let's set up a loading indicator in our markup:

<div id="loading" style="display:none;">Loading...</div>

现在,让我们创建一些JavaScript:

Now lets create some javascript:

// Show the loading indicator, then start a SYNCRONOUS ajax request
$('#loading').show().delay(100).queue(function() {
    var jqxhr = $.ajax({type:"GET",dataType:"json",url:"www.yoururl.com/ajaxHandler",async: false}).done(function(){
        //Do your success handling here
    }).fail(function() {
        //Do your error handling here
    }).always(function() {
        //This happens regardless of success/failure
        $('#loading').hide();
    });
    $(this).dequeue();
});

首先,我们要显示我们的负荷指标,然后给浏览器有延迟重绘我们syncronous XHR请求被启动之前。通过使用jQuery的 .queue()的方法,我们正在把我们的阿贾克斯()调用默认FX队列,以便它不会后才执行 .delay()完成,这当然不会发生后才 .show()完成。

First, we want to show our loading indicator and then give the browser a moment delay to repaint before our syncronous XHR request gets started. By using jQuery's .queue() method we are putting our .ajax() call in the default fx queue so that it won't execute until after the .delay() completes, which of course doesn't happen until after the .show() completes.

jQuery的 .show()方法改变目标元素的CSS显示样式来阻止(或指定的恢复初始值)。这种变化在CSS会导致浏览器回流(又名重绘),只要它能够。延时保证了它能够在Ajax调用之前回流。延迟是没有必要在所有的浏览器,但不会伤害比你指定的毫秒数的话(像往常一样,IE浏览器将在这里的限制因素,其他浏览器很高兴与1ms的延时,即想要的东西一点点更显著重画)。

The jQuery .show() method changes the target element's CSS display style to block (or restores its initial value if assigned). This change in CSS will cause the browser to reflow (aka "redraw") as soon as it is able. The delay ensures that it will be able to reflow before the ajax call. The delay is not necessary in all browsers, but won't hurt any more than the number of milliseconds you specify (as usual, IE will be the limiting factor here, the other browsers are happy with a 1ms delay, IE wanted something a little more significant to repaint).

下面是一个的jsfiddle为您测试在几个浏览器:的jsfiddle例如

Here's a jsfiddle for you to test in a few browsers: jsfiddle example

这篇关于力UI重新绘制在WebKit的(Safari浏览器和放大器; Chrome浏览器)同步&QUOT前右;阿贾克斯&QUOT;请求的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆