【问题标题】:How to invoke a "Please Wait" window only if ajax takes more than X milliseconds to respond?仅当 ajax 响应时间超过 X 毫秒时,如何调用“请稍候”窗口?
【发布时间】:2011-09-07 15:22:41
【问题描述】:

我正在执行 AJAX 调用(常规 JS),如果它需要超过 500 毫秒,我想打开我的“请稍候”框。

一般情况下,如果我想立即把密码箱放上去,我会这样做:

// show semi-transparent grey screen to block access to everything underneath
divGreyCoverAllNode.style.display = 'inline';
// show PW box. Prior to these lines, both coverall and PW were display=none
divPleaseWaitNode.style.display = 'inline';

// now do the AJAX and follow-up inside a zero timer; the timer is necessary to
// make the system pause to display the screen changes we previously invoked 

setTimeout( function() {
        // do my ajax call here, then after the call...
        // take down the PW stuff
        divPleaseWaitNode.style.display = 'none';
        divGreyCoverAllNode.style.display = 'none';
    },
    0
);

就像我上面所说的,我想做的是仅当 AJAX 没有在 500 毫秒内完成时才显示 PW。理想情况下是这样的:

// set a timer to display PW in 500 milliseconds
myTimeEvent = setTimeout( function() {
        divGreyCoverAllNode.style.display = 'inline';
        divPleaseWaitNode.style.display = 'inline';
    },
    500
);

// do my ajax call here, then after the call...
clearTimeout(myTimeEvent);
// take down the PW stuff, in case it was displayed
divPleaseWaitNode.style.display = 'none';
divGreyCoverAllNode.style.display = 'none';

但是当 AJAX 占用时间时,我似乎无法让系统暂停并显示 PW。我已经尝试在零计时器中围绕 AJAX 和后续块,但没有处理。

有什么建议吗?

编辑: 重要事实:这不是异步 ajax 调用。这是一种不寻常的情况,需要一切都等待 ajax 结果。

【问题讨论】:

  • 你把clearTimeout放在ajax调用的响应部分了吗?你的问题不清楚
  • clearTimeout 在我得到 AJAX 调用的结果后立即出现。它不是onreadystatechange 函数的一部分。但这是一个相当奇怪的 ajax 调用,因为它不是异步的。

标签: javascript html settimeout


【解决方案1】:

鉴于您正在进行同步 XHR 调用,您不能。这就是同步的本质——一切都会停止,直到调用完成。当您使用同步 XHR 请求时,不仅 JavaScript 事件循环停止,而且实际上冻结了整个浏览器 UI(在 IE 和 Firefox

也就是说,you're doing it wrong8.4% 上个月报告的 IE9 挂起是由于同步 XHR。确实没有这样的事情,即“需要使用同步 XHR 请求的不寻常情况。”提出您的请求,然后对您在回调函数中获得的数据采取行动。

而不是类似的东西:

// Do stuff, then when you need a request:
var xhr = new XMLHttpRequest();
xhr.open('GET', url, false);
xhr.send();
// Do more stuff
alert(xhr.responseText);

你需要:

// AJAX helper
function req(url, callback) {
  var xhr = new XMLHttpRequest();
  xhr.open('GET', url, true);
  xhr.onreadystatechange = function() {
    if (xhr.readyState == 4 && xhr.status == 200) callback(xhr);
  }
}


// Your code.  Do stuff, then when you need an AJAX request:
req(url, function(xhr) {
  // Do more stuff
  alert(xhr.responseText);
});

显然这需要改进,但这说明了发出 AJAX 请求的正确方法。

【讨论】:

  • 因此,由于这是一个在用户执行其他操作之前我必须完成的过程,因此异步执行此操作的方法是:1:显示 PW 以使用户无法访问对象,2:使处理后带有回调的 AJAX 调用以删除 PW。对吗?
  • 您需要防止与之交互的对象是什么?如果它是一个表单,我会禁用表单中的所有元素,直到一切准备就绪。请记住,使用覆盖只会阻止鼠标交互——仍然可以使用键盘。我确实喜欢您希望在显示“请稍候”之前稍等片刻——我记得看到一些研究(我现在找不到链接)表明用户会感知您的应用程序更快如果您没有显示任何类型的“正在加载...”指示器当它是快速加载时。在n ms 之后,您需要一个指示器,以便他们知道发生了什么事。
  • 它有两种形式,一个 CSS 菜单,以及一些带有相关链接的标题标志,以及页面本身的一些链接。页面发生了很多事情。
  • 在纯 JS 中禁用表单可能是一个挑战(使用 jQuery,你可以只做 $('form *').attr('disabled','disabled');),你可以在你的菜单中添加一个 disabled 类并添加一些 CSS 来防止它开幕。我会为链接做类似的事情——添加一个disabled类,然后有类似$('a').live('click', function(e) { if ($(this).hasClass('disabled') e.preventDefault(); });
【解决方案2】:

它不应该出现在 ajax 调用之后,它应该出现在回调函数内部。 AJAX 请求与其余代码是异步的,您应该在请求的回调部分完成后执行您想要的操作。

【讨论】:

  • 抱歉,我刚刚添加了一个编辑。我一开始没有指出这一点很糟糕。这个 ajax 不寻常,因为它不是 异步的。一切都在等待结果。
  • 我仍然可以将 clearTimeout 添加到 onreadystatechange 函数中,但我不确定这将如何帮助 PW 首先出现。
【解决方案3】:

看看BlockUi。如果这看起来不适合您,您可以尝试使用

$(document).ajaxStop(DoSomething()); 

【讨论】:

  • 谢谢。不过,我没有使用 jQuery。
  • 有什么特别的原因吗?我的意思是 jquery 甚至有 $fn.solveWorldHunger() 和 $fn.PeaceForEveryOne() :)
  • 整个客户网站都是纯JS。改变是一项比值得付出更大的努力。这可以在纯 JS 中完成;雷西格做到了。 :)
  • 您不必重新更改所有内容。您甚至不必在任何其他页面中使用 jquery。 jquery 仍然是 javascript,它只是 javascript 之上的一个库。我确信它可以在 POJ 中完成,但有时是关于继续它而不是重写代码(无论如何对我来说)
  • 好点。我想无论如何我都会在这个项目上坚持使用 POJ。它让我在很多场合都深入了解了 jQuery 幕后实际发生的事情。这很有价值。
【解决方案4】:

【讨论】:

  • 我没有使用 jQuery,但请告诉我更多关于这如何帮助 PW 框出现的信息。也许我可以从代码中窃取一些想法。 :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-07-29
  • 2020-12-27
  • 2012-03-10
  • 1970-01-01
  • 1970-01-01
  • 2011-08-10
  • 1970-01-01
相关资源
最近更新 更多