【问题标题】:Chrome AJAX on page-load causes "busy cursor" to remain页面加载时的 Chrome AJAX 导致“忙碌光标”保留
【发布时间】:2011-09-11 09:04:21
【问题描述】:

在 Google Chrome 中,AJAX 在 $(function(){....}); 内调用似乎保持页面加载。

我的网站有几个带有标签的页面。因为我使用的是廉价的 Godaddy 主机,所以我希望页面加载速度尽可能快。因此,我想在 1 个选项卡上加载一个页面,然后在后台使用 AJAX 加载其他选项卡。当我从

运行 AJAX
$(function(){
    /*AJAX CODE HERE */
});

光标显示页面长时间加载(http://jsfiddle.net/mazlix/7fDYE/9/

我已经找到了一种方法(至少在 chrome 中)使用setTimeout(); (http://jsfiddle.net/mazlix/7fDYE/8/) 来解决这个问题,但这只有在您正确预测窗口何时完成完全加载并且显然需要更长的加载时间时才有效.我想要一种在页面加载后立即通过 AJAX 加载内容的方法,因此在等待返回的 AJAX 时不会显示“忙碌光标”。

【问题讨论】:

  • 还有其他的吗?看看我的 jsfiddles 的代码.. 如果我做错了 AJAX 调用虽然我不知道为什么会出现..
  • FWIW 它在 FF4 和 IE9 中运行良好。如果 setTimeout 技巧在 Chrome 中处理它,那么我会说去吧。我不确定为什么 Chrome 会选择这种行为:例如这是故意的还是副作用? (AJAX/XHR 可以同步运行,但不是在那个例子中。)
  • 请在下面重新测试我的答案,使用 window.load 而不是准备好文档。我相信它现在有效。
  • 我没有看到 chrome 中的光标有任何问题,请查看我的 jsFiddle

标签: javascript jquery ajax google-chrome loading


【解决方案1】:

只要没有对服务器的新查询,Google Chrome 就会显示加载指示符。在显示加载指示器时,所有新请求都会导致 Chrome 延长指示器显示的时间。此外,当指示器显示时按下esc,所有请求都将中止!其中包括 AJAX 请求甚至 Flash 请求!看看this question:我以为是Youtube的原因,结果变成了Chrome的惯用行为。

避免“延长”显示加载指示器时间的唯一方法是在加载指示器隐藏后发出请求:即当所有对服务器的查询都完成时。 JQuery's documentation .load() 说:

当一个元素和所有子元素都被完全加载后,加载事件会被发送到该元素。此事件可以发送到与 URL 关联的任何元素:图像、脚本、框架、iframe 和窗口对象。

因此,如果您确定页面上只有图像、脚本和框架,window.load() 将在您需要时触发。将setTimeout() 添加到它会随心所欲地工作。这是一个例子:http://jsfiddle.net/7fDYE/22/

如果在您的请求之前还有其他请求,您应该等待它们完成!例如,您知道除了图像/脚本等之外,在页面加载之前您还有 3 个 AJAX 请求。你可以有这样的东西:

var loaded=0,needsToBeLoaded=4; //3 AJAX + window
function onLoad(){
    loaded++;
    if(loaded==needsToBeLoaded){
         //do the AJAX request   
    }
}
window.load(onLoad);
// add onLoad() to all 3 AJAX request handlers

我不确定您可以使用 Flash 请求做什么...

【讨论】:

  • 等待所有请求触发加载的好主意。这应该可以解决问题。
  • 您可以订阅特殊事件ajaxStop并将您的ajax请求放入其处理程序中,然后取消订阅以免再次执行
【解决方案2】:

更新

此解决方案不适用于 Chrome。只有在窗口加载之前发出的所有请求都完成时,它才会停止加载指示器。唯一的解决方案似乎是让它在窗口加载后发出请求,但据我所知,这只能通过 setTimeout 实现,这不是很好。


更新

要解决 Chrome 中的指针问题,您可以设置光标样式,如 this fiddle 所示。这有点 hacky,它没有解决选项卡顶部的加载指示器问题。


加载指示器将在浏览器中显示,直到页面加载(窗口的加载事件)。在$(function(){someCode();}); 中,someCode 在触发 DOM 加载事件时执行(当所有内容已被解析并插入 DOM 时,在页面加载之前)。此时 JavaScript 的执行会阻止窗口的加载事件触发,从而阻止加载指示器停止。请注意,图像加载也会阻塞窗口的加载事件。

相反,您可以尝试$(window).load(function(){someCode();});。在这个例子中,someCode 在窗口的加载事件被触发时被执行。这是浏览器的加载指示器停止的地方。

所以,而不是:

$(function(){
    /*AJAX CODE HERE */
});

试试:

$(window).load(function(){
    /*AJAX CODE HERE */
});

请注意,这可能会导致您的 JavaScript 稍后开始执行,这可能是不可取的。

【讨论】:

  • 如果我理解正确,那也不起作用,看看在使用 chrome 时,favicon 和 busy-cursor 如何保持加载,直到 AJAX 完成。 jsfiddle.net/mazlix/7fDYE/12
  • 抱歉,Chrome 似乎不会停止加载指示器,直到在窗口加载事件完成冒泡之前开始执行的所有 JavaScript 完成。因此,如果您的脚本在窗口加载发生时启动,它将阻止加载指示器,因为脚本启动时窗口加载尚未完成。其他浏览器的行为是明智的。看起来解决这个问题的唯一方法是使用 setTimeout(如this)。虽然这不是一个很好的解决方案...很难预测窗口加载事件何时完成并且意味着稍后会加载内容。
  • 这是已知的 chrome 问题吗?还是他们不认为这是一个错误?有没有其他你能想到的技巧,比如 body.hover() [除了我认为它不适用于移动设备]
  • 我认为这是预期的行为(因为页面实际上还没有完成加载)。我能想到的唯一解决方法是 setTimeout ,这不是很好。我认为您可能能够侦听要聚焦在页面上的第一个元素的焦点事件,但这可能发生在窗口加载之前。我只会使用窗口加载事件并承认 Chrome 的失败。
  • 我提供了一个赏金来尝试鼓励解决方案,我真的希望 AJAX 不会导致“忙光标”
【解决方案3】:

有一个超级简单、万无一失的解决方案:

将您的函数包装在 setTimeout 调用中,并使用 0 的间隔。这将使函数排队等待立即调用,但 Chrome 将不再等待它加载后才考虑页面“完成”。您不需要对页面何时完成进行任何猜测,只需确保您在 jquery Ready 处理程序中调用 setTimeout,如下所示:

$(window).load(function() {
    setTimeout(function() {
        $("#result").html(ajax_load);
        $.post("/echo/json/", {json: json1, delay: 10000}, show_json, "json");
    }, 0);
});

【讨论】:

  • 这行不通!看一下:jsfiddle.net/7fDYE/20 我添加了一个<img>,图像文件比较大。在加载图像之前,浏览器的加载指示器不会停止。但$(function(){ ... }) 将在此之前工作,AJAX 将在 页面加载完成之前调用,Chrome 将等待 AJAX 调用完成
  • 你是对的,我的错。实际上,您必须附加到 window.load,而不是准备好文档。我已经编辑以反映这一点。
【解决方案4】:

根据 JQuery 文档,例如,在准备好之前不应运行任何 javascript

$(document).ready(function() {someCode();});

考虑到这一点,我更改了您的 jsFiddle(加载需要一些时间,但可以)

编辑:没有分叉 jsfiddle >

【讨论】:

  • 你说加载需要一些时间,但它没有加载..它已经完成“加载”它只是“等待”。如果我在您的示例中按 ESC,则信息永远不会出现,但请查看带有 setTimeout 的示例,他们没有这个问题
  • 我在 chrome 版本 12.0.742.100 上运行良好,它正在等待准确的延迟时间(将延迟更改为 delay: 0 以进行即时回调),您正在测试什么版本?跨度>
  • 但它不应该等待延迟时间。看看另一个例子,在那个例子中,一旦加载了所有东西,光标就会完成..因为它等待回调 jsfiddle.net/7fDYE/22 ,在这个例子中,chromes 的行为与 firefox/i.e. 相同
【解决方案5】:

我不确定我是否同意这是一个问题。我想说这是 chrome 的理想行为,因为它表明它实际上还没有完成加载。我会说 Firefox 实际上是不正确的,因为它没有表明它仍在等待脚本回调完成。

这可能是个人喜好问题(我喜欢浏览器表明它正在等待/工作,即使它使我的浏览器看起来很慢),在这种情况下,成功“修复”这个“问题”,将使浏览器的行为不像用户习惯的那样。在 Web 开发中,您真的不应该尝试强制浏览器以对 web 应用程序的工作方式不重要的特定方式运行,因为您最终可能会强制执行您使用的操作系统的外观以不同的感觉进入另一个操作系统,让另一个操作系统的用户感觉更陌生(即使它让网站对你来说更本地化)。

忙碌的光标无论如何都不是问题,因为元素已经加载,仍然是响应式的。

【讨论】:

  • 我同意,但是如果 看起来 页面已经完成加载,很多用户会“更快乐”。不过,我并不是说这是个好主意。
【解决方案6】:

看起来这是一个 Chrome 问题,他们没有修复它: https://bugs.chromium.org/p/chromium/issues/detail?id=26723

【讨论】:

  • 虽然此链接可能会回答问题,但最好在此处包含答案的基本部分并提供链接以供参考。如果链接页面发生更改,仅链接答案可能会失效。 - From Review
  • @ReeganMiranda 这看起来很可能是一个有用的答案。请查看when to delete in LQP
猜你喜欢
  • 1970-01-01
  • 2011-05-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-06
相关资源
最近更新 更多