【问题标题】:Detect when user clicks link, but aborts检测用户何时单击链接但中止
【发布时间】:2009-11-21 19:21:19
【问题描述】:

我正在开发 Web CMS。当用户点击链接移动到其他页面或提交表单时,我希望在右上角显示“请稍候”动画 GIF,以表示正在加载。

但是,用户可以在浏览器中取消加载新页面,例如按“取消”按钮或 ESC。在这种情况下,当浏览器停止加载下一页时,它们将停留在当前页面上。

如何在 Javascript 中检测到这一点,并再次隐藏“等待”图标?

编辑:为了解决“你不应该那样做,浏览器已经拥有它”的问题。引入自定义解决方案有两个具体原因。

  • 我在页面上有 AJAX 按钮。我需要一个活动指示器,这样用户就不会混淆点击是否注册。

  • 在延迟很大的慢速连接上,某些浏览器的进度条会移动得非常慢。我处于现实生活中的工作环境中,需要很长时间才能在 IE6/7 中显示任何类型的活动。这给人的印象是什么都没有发生,应用程序的反应非常缓慢,这让我很恼火。我想要一个不断变化的指标(例如 Safari 的)。

【问题讨论】:

  • 我总是觉得那些“等待”和“加载”的事情很烦人。浏览器默认拥有它(FireFox/Safari 中的微调器和 IE 中的进度条)。最好考虑不添加?
  • 在缓慢的系统和连接上,尤其是 IE 在传达它当前正在做的事情时非常模糊。在某处弹出的快速符号可以解决这种情况。
  • 关于 AJAX 点,如果你使用 jQuery,有全局事件处理程序做得很好。看看我一直在玩 jsfiddle.net/e4z9bv6k 的小提琴,还有一些有用的 SO 帖子 stackoverflow.com/q/3735877 和 stackoverflow.com/q/9043768 以及 stackoverflow.com/q/3709597
  • +1 表示您的第二点,即使在 2014 年,现实生活中的工作情况也需要永远加载页面并且在某些浏览器(即 Chrome)中“只有”一个小加载图标在浏览器的左上角显示正在加载的页面。添加跨浏览器自定义样式对我来说似乎是合法的。

标签: javascript internet-explorer firefox events


【解决方案1】:

抱歉,我不认为有任何方法可以做到这一点,不。我的意思是你可以发现一个转义键,这是值得的,但是没有一般的方法来检测取消下一页加载。除了猜测如果您在提交/点击后仍然大约几秒钟,那么它要么已被取消,要么您的服务器很慢。或者在同一个页面中使用 AJAX 完成整个导航和提交的工作,这可以通过破坏浏览器自身的停止按钮来避免问题;可能不是一个好主意。

(无论如何,添加您自己的等待抖动器并不是一个好主意;浏览器有一个非常好的自己的!)

【讨论】:

  • 我同意,打破停止按钮不好。嗯,如果不能做到这一点,那就太糟糕了。至于跳动者,请参阅我在上面的问题中的编辑。
  • 进度条慢的时候,是不是因为你在做大表单提交?如果是这样,将其分解为 AJAX 表单提交并带有自己的 throbber 和快速导航应该不难。
【解决方案2】:

我认为您应该检查所谓的“锚导航”。这里有一个很好的教程:

http://yensdesign.com/2008/11/creating-ajax-websites-based-on-anchor-navigation/

基本上,您会将用户引至相同的 URL,但最后带有锚点 (http://localhost/home#somepage?param1=val1) 并使用 AJAX 加载数据。 Javascript 将捕获锚点更改,并可以显示“加载”图标并提供其他内容,例如“取消加载”。在这种情况下,您将拥有浏览器历史记录,因此您可以在浏览器中说“返回”或在 javascript 中说 history.go(-1)。

【讨论】:

  • 切换到 AJAX 提交并不是一个真正的选择,因为它是一个复杂的系统,所以太麻烦了。不过谢谢你的想法。
  • 如果你想实现那个功能,无论如何你都必须使用javascript。另外,我相信这不会适用于每一页,所以应该不难。不是使用此锚导航的 GMail :) 实际上,您可以检查以下内容:打开 GMail,关闭互联网连接并在“收件箱”和“已发送”之间切换 - 您将看到“页面未加载”,但不是 404 错误!
  • @Vitaly 正如 Pekka 指出的那样,锚导航意味着从常规表单提交(由浏览器处理)切换到 AJAX 表单提交(由您以编程方式处理)。是的,Gmail 和其他单页应用程序通过以编程方式执行一些客户端路由来做一些很酷的事情,但如果您不是首先构建单页应用程序,这可能不是您想要做的事情。见read.humanjavascript.com/ch09-clientside-routing.html
  • 请注意,Pekka 正在寻找一个通用的解决方案,因此可以在他的整个网站上使用...
【解决方案3】:

这不适用于提交按钮。一旦用户点击“提交”,请求就被发送到服务器。一旦发生这种情况,就执行了操作。在这种情况下,您能做的最好的事情就是阻止用户看到他们的操作的响应,但该操作仍会执行。

此外,一旦启动另一个请求,阻止用户导航到另一个页面的唯一方法是将用户重定向回他们来自的页面。一般来说,取消请求只是一个普通的 Bad Idea™

对于表单,另一种选择是对所有表单提交使用 AJAX。 AJAX 请求可以被取消,因此您可以利用它来发挥自己的优势,尽管它会使事情变得更加复杂和难以处理。

如果你仍然想经历这个,但知道其中的含义,你可以很容易地做到这一点with a JavaScript framework,比如jQueryYUIDojoMooToolsExtJS 或 @987654327 @。

这是一个如何在 jQuery 中执行此操作的示例。正如我所提到的,如果不刷新用户所在的页面(以停止当前页面加载),就无法在请求启动后停止请求,因此我在此示例中省略了该部分。

$().ready(function() { 
    function showLoading(){  
        $loadingOverlay = $('<div id="loadingOverlay"></div>'); 
        $loadingAnimation = $('<div id="loadingAnimation">Loading...</div>'); 
        $("body").prepend($loadingAnimation).prepend($loadingOverlay); 
    } 

    $("a[href]").click(showLoading); 
    $("form").submit(showLoading); 
});

要在加载框中添加动画 gif,请将文本“Loading...”替换为指向您选择的加载 gif 的 &lt;img /&gt; 标记。可以在这里看到一个现场演示:http://jsbin.com/opadi

你需要这个 CSS 来配合上面的代码:

#loadingOverlay {
    position: absolute; 
    top: 0px; 
    left: 0px; 
    height: 100%; 
    width: 100%; 
    z-index: 1000; 
    background: #000;
    filter:alpha(opacity=50);
    -moz-opacity:0.5;
    -khtml-opacity: 0.5;    
    opacity: 0.5;
}
#loadingAnimation {
    position: absolute; 
    top: 30%; 
    left: 50%;
    z-index: 1001;
}

【讨论】:

  • 我的关注点不是动作是否被执行——这是用户的责任。如果操作已被取消,并且没有发生页面更改,我只想再次正确隐藏符号。我正在寻找可以参与的活动或可靠的解决方法。
  • 从可用性的角度来看,这听起来是个坏主意。你永远不应该有一个实际上不会取消任何东西的“取消按钮”。您所做的实际上只是创建了一个取消按钮,该按钮除了隐藏取消按钮外没有其他功能,而不是用户期望取消的操作。
  • 不,你不明白,我想检测用户何时使用浏览器内置的取消按钮或转义键取消加载下一页。用户的工作流程没有改变。
  • 感谢 Dan,提供了大量示例。将表单提交和/或导航切换到 AJAX 会在复杂系统中产生太多影响,所以这不是我的选择。我已经澄清了我的问题,以强调我并没有试图以编程方式取消请求。
【解决方案4】:

(是的,我确实喜欢老话题)

我在这里面临同样的情况。我正在构建一些通过表单提交完成导航的页面,我发现在用户退出并触发 15 次相同请求之前清楚地向用户显示正在发生的事情很方便——“我们不信任用户,做我们?”

所以我使用 jQuery 和一个不错的插件 maned Impromptu,可以在 http://trentrichardson.com/Impromptu/index.php 找到

这是一段代码:

$(document).ready( function () {

 $("form").submit( function() {
  $.prompt( "<center>Sending request...</center>", {
   overlayspeed: 200,
   buttons:{}
  });

  setTimeout( "jQuery.prompt.close()", 2000 );
 });

});

【讨论】:

  • 不回答问题。 Pekka 正在寻找一种通用解决方案来检测浏览器上的“取消”操作。
【解决方案5】:

我不相信可以检查用户是否以跨浏览器的方式点击了 STOP 按钮,但是要找到问题的根源,您可以自己监控请求:

当你运行你的 xhr 请求时,用onreadystatechange 注册一个函数。检查是否xhr.readyState === XMLHttpRequest.DONE。检查请求是否成功的指示器(挥手,欢迎编辑)。如果它没有成功,那么它以某种方式被打断了,你应该恢复你的进度指示器。

如果这是一种常见情况,您可以通过猴子修补来自动执行此操作。见this question

如果是 POST,您可能还应该警告用户取消他们的请求不会阻止数据更改。您可以在这里变得更复杂,并自动反转 POST 请求或告诉他们究竟更改了什么,以便他们做出决定。

希望有帮助!

【讨论】:

    【解决方案6】:

    window.onabort 似乎是一个很有前途的解决方案,但目前(2020-05-02)它被标记为仅受 Chrome 和 Edge 支持的实验性技术。此外,它似乎是为处理加载现有页面或资源而不是下一页而设计的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-11-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-05-31
      • 2018-03-06
      • 2012-12-18
      相关资源
      最近更新 更多