ajax - 在同步 "Ajax"请求之前强制在 Webkit(Safari 和 Chrome)中重新绘制 UI

标签 ajax jquery webkit

在一个简单的基于 Ajax 的网站中,我们同步发出一些 HttpRequests 请求(我意识到“同步 Ajax”有点矛盾)。同步与异步完成的主要原因是为了简化某些相关人员的编程模型(长话短说)。

无论如何,我们希望能够在发出请求之前进行样式更改(具体来说,像 Google 搜索那样用半透明的白色覆盖屏幕),然后在结果返回时将其取消。本质上这看起来像:

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

众所周知,同步请求会锁定 UI。因此,毫不奇怪,白色覆盖层从未出现在 Safari 和 Chrome 中(有趣的是,它在 Firefox 中出现)。我尝试过减慢响应速度并使用粉红色覆盖层,这样它就会非常明显,但直到请求完成后它才会更新用户界面。保留 'busyMask.className="Hidden"' 部分将会显示掩码——但只有在 ajax 请求完成后才会显示。

我见过很多强制 UI 重绘的技巧(例如 Why HourGlass not working with synchronous AJAX request in Google Chrome?http://ajaxian.com/archives/forcing-a-ui-redraw-from-javascript ),但它们似乎都与尝试显示实际的“永久”DOM 或样式更新结合在一起,而不是与在发出同步请求时暂时显示样式更改。

那么有没有办法做到这一点,或者我正在打一场失败的战斗?也许我们只需要针对性能最差的请求根据具体情况切换到异步请求,这可能是解决学习曲线问题的一个不错的方法......但我希望有一个外部方法盒子的答案在这里。

最佳答案

好吧,出于这个问题的目的,我将忽略为什么需要同步 XHR 请求的理由。我知道有时工作限制不允许使用最佳实践解决方案,因此我们“凑合”以完成工作。因此,让我们重点关注如何让同步 ajax 与视觉更新为您工作!

考虑到您正在使用 jQuery 来处理 XHR 请求,我假设可以使用 jQuery 来显示/隐藏加载指示器并处理任何计时问题。

首先让我们在标记中设置一个加载指示器:

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

现在让我们创建一些 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();
});

首先,我们想要显示加载指示器,然后在我们的同步 XHR 请求开始之前给浏览器一些延迟来重新绘制。通过使用 jQuery 的 .queue() 方法,我们将 .ajax() 调用放入默认的 fx 队列中,以便它在 之后才会执行。 delay() 完成,这当然要等到 .show() 完成之后才会发生。

jQuery .show() 方法将目标元素的 CSS 显示样式更改为 block (或恢复其初始值(如果已分配))。 CSS 中的此更改将导致浏览器尽快重排(又名“重绘”)。延迟确保它能够在 ajax 调用之前回流。延迟在所有浏览器中并不是必需的,但不会造成超过您指定的毫秒数的影响(像往常一样,IE 将是这里的限制因素,其他浏览器对 1 毫秒的延迟感到满意,IE 想要一些东西重新绘制更重要)。

这里有一个 jsfiddle 供您在几个浏览器中测试:jsfiddle example

关于ajax - 在同步 "Ajax"请求之前强制在 Webkit(Safari 和 Chrome)中重新绘制 UI,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8040279/

相关文章:

css - Chrome 及其对 %s 的处理

mysql - 查询 MySQL 数据库客户端

javascript - 预览后 - 使用 AJAX 和 Fancybox 传递数据

java - 如何从 Java Rest Web 服务返回 ajax 中的值?

jquery - 通过ajax ping web 服务

javascript - 如何检查条件并将额外参数传递给语义用户界面搜索?

javascript - 在 jQuery 中添加和删除克隆?

javascript - 使用 javascript 激活 css 转换

css - Chrome 中的位置固定

php - 在选项卡上单击加载内容