检测用户何时单击链接,但中止

Detect when user clicks link, but aborts

提问人:Pekka 提问时间:11/22/2009 最后编辑:CommunityPekka 更新时间:5/3/2020 访问量:3086

问:

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

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

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

编辑:为了解决“你不应该这样做,浏览器已经有了”的评论。我有两个具体原因来引入自定义解决方案。

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

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

JavaScript Internet-Explorer Firefox 事件

评论

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

答:

1赞 Dan Herbert 11/22/2009 #1

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

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

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

如果你仍然想完成这个,知道其中的含义,你可以用 JavaScript 框架,如 jQueryYUIDojoMooToolsExtJSClosure 轻松完成。

下面是如何在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,请替换文本“正在加载...”带有指向您选择的加载 GIF 的标签。可以在此处看到此演示的现场演示: http://jsbin.com/opadi<img />

你需要这个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;
}

评论

1赞 Pekka 11/22/2009
我的重点不是是否执行了操作 - 这是用户的责任。我只想在操作已取消且未发生页面更改的情况下再次正确隐藏该符号。我正在寻找一个我可以联系的事件,或者一个可靠的解决方法。
0赞 Dan Herbert 11/22/2009
从可用性的角度来看,这听起来是个坏主意。你永远不应该有一个实际上不会取消任何事情的“取消按钮”。您所做的实际上只是创建一个取消按钮,该按钮除了隐藏取消按钮外没有任何功能,但不是用户期望取消的操作。
1赞 Pekka 11/22/2009
不,你不明白,我想检测用户何时使用浏览器内置的取消按钮或转义键取消了下一页的加载。用户的工作流不会更改。
1赞 Pekka 11/22/2009
但感谢 Dan 提供了大量示例。在复杂的系统中,将表单提交和/或导航到 AJAX 会产生太多影响,因此这对我来说不是一个选择。我已经澄清了我的问题,以强调我不是试图以编程方式取消请求。
1赞 Vitaly 11/22/2009 #2

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

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

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

评论

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

对不起,我认为没有任何方法可以做到这一点,没有。我的意思是,您可以发现一个转义键,但目前还没有通用的方法来检测下一页加载的取消。除了猜测如果您在提交/点击后仍有几秒钟的时间,那么它要么被取消了,要么您的服务器速度很慢。或者在同一页面中使用 AJAX 完成整个导航和提交工作,只需破坏浏览器自己的停止按钮即可避免问题;可能不是一个好主意。

(我不认为添加一个你自己的等待悸动真的是一个好主意;浏览器有一个非常好的浏览器!

评论

0赞 Pekka 11/22/2009
我同意,打破停止按钮是不好的。嗯,如果做不到,那就太糟糕了。至于悸动,请参阅我在上面的问题中的编辑。
0赞 bobince 11/22/2009
当进度条很慢时,是因为您正在进行大型表单提交吗?如果是这样,那么将其分解为具有自己的悸动的 AJAX 表单提交,然后是快速导航应该不难。
1赞 Randoum 2/19/2011 #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 );
 });

});

评论

0赞 Adriano 9/15/2014
没有回答问题。Pekka 正在寻找一种通用解决方案来检测浏览器上的“取消”操作。
0赞 DylanYoung 2/15/2018 #5

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

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

如果这是一个常见的场景,你可以通过猴子修补来自动完成此操作。请参阅此问题

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

希望对您有所帮助!

0赞 abbr 5/3/2020 #6

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