识别刷新和closures浏览器操作

当我们刷新页面(F5或浏览器中的图标)时,它将首先触发ONUNLOAD事件。 当我们closures浏览器(右上方的X图标)时,会触发ONUNLOAD事件。 现在当ONUNLOAD事件被触发时,无法区分刷新页面或closures浏览器。 如果你有任何解决scheme,然后给我。

有一个解决scheme。

我想在标签页或浏览器窗口closures时断开服务器上的用户连接,但是当页面被重新加载(为了不同的目的,您可能想区分重新加载/closures事件,但是您可以从我的解决scheme中获益)。 基于HTML5的本地存储和客户端/服务器AJAX通信,我结束了以下过程:

  1. 在你的页面上,添加一个onunload到下面的处理程序的window (pseudo-javascript):

     function myUnload(event) { if (window.localStorage) { // flag the page as being unloading window.localStorage['myUnloadEventFlag']=new Date().getTime(); } // notify the server that we want to disconnect the user in a few seconds (I used 5 seconds) askServerToDisconnectUserInAFewSeconds(); // synchronous AJAX call } 
  2. 在你的页面上,在body上添加一个onload到下面的处理程序(pseudo-javascript):

     function myLoad(event) { if (window.localStorage) { var t0 = Number(window.localStorage['myUnloadEventFlag']); if (isNaN(t0)) t0=0; var t1=new Date().getTime(); var duration=t1-t0; if (duration<10*1000) { // less than 10 seconds since the previous Unload event => it's a browser reload (so cancel the disconnection request) askServerToCancelDisconnectionRequest(); // asynchronous AJAX call } else { // last unload event was for a tab/window close => do whatever you want (I do nothing here) } } } 
  3. 在服务器上,收集列表中的断开连接请求,并设置定期检查列表的定时器线程(我每20秒使用一次)。 一旦断开连接请求超时(即5秒钟不见了),请断开用户与服务器的连接。 同时接收到断开请求取消的情况下,将相应的断开请求从列表中移除,使得用户不会被断开。

如果您想区分标签页/窗口closures事件和后续链接或提交的表单,这种方法也适用。 您只需要在包含链接和表单的每个页面上以及每个链接/表单着陆页上放置两个事件处理程序。

请注意,我使用unload事件而不是beforeUnload事件来正确pipe理附件的链接:当用户点击附件的链接(例如PDF文件)时,调度beforeUnload事件,然后打开/保存popup窗口(仅仅是浏览器不会改变显示的页面,不会发送unload事件)。 如果我使用beforeUnload事件(就像我之前做的那样),如果没有,我会检测到一个页面的变化。

这种方法仅限于支持HTML5本地存储的浏览器,因此您可能会对旧版浏览器(如MSIE7)使用特定的方法。

基于event.clientY其他方法是不可靠的,因为当点击重载或标签/窗口closuresbutton时该值为负值,而当键盘快捷键用于重载时(例如F5,Ctrl-R,…)窗口closures(例如Alt-F4)。 依赖于事件X的位置也是不可靠的,因为button没有放在每个浏览器的相同位置(例如左边的closuresbutton)。

不幸的是,检查事件的clientY / pageY值(正如这里的一些答案所build议的)不是一种可靠的方式来确定是否由于用户closures页面而导致unload事件被触发。

当您点击浏览器的closuresbutton时,客户clientY / pageY为负的原因是因为closuresbutton位于文档的顶部之上(即在像素0之上),但重新加载button也意味着点击重新加载button也会导致clientY / pageYpageY

沿着检查事件的x坐标的path也是有问题的,因为浏览器closuresbutton并不总是在窗口的右侧(例如它在OS X的左侧),并且因为可以closures窗口通过closures其标签或通过键盘。

使用window.onbeforeunload事件的情况下离开页面,但它将包括刷新或定位标签….使用相同的validation标志,该过程的一个例子是URL检查(初始URL =当前URL )或F5检查使用键码进行刷新,如果锚标签使用bind()

注意* Chrome代码可能会导致问题。

 <!DOCTYPE HTML> <html> <head> <meta http-equiv="Content-type" content="text/html;charset=UTF-8"> <title>Test Page</title> <style type='text/css'> body { font-family: sans-serif; } </style> <script src="jquery-1.9.1.js" type='text/javascript'></script> <script type='text/javascript'> var valid=false; function wireUpEvents() { if(valid){ alert("Page Refreshed or Redirected"); }else{ window.onbeforeunload = askWhetherToClose; } function askWhetherToClose(event) { if(!valid){ var msg; msg = "You're leaving the page, do you really want to?"; event = event || window.event; event.returnValue = msg; return msg; }} $(document).bind('keypress', function(e) { if (e.keyCode == 116){ // or you can insert some code to check page refresh valid = true; //wireUpEvents(); } }); $("a").bind("click", function() { //To check redirection using Anchor tags valid = true; //wireUpEvents(); }); } $(document).ready(function() { wireUpEvents(); }); </script> </head> <body> <p>Close the browser window, or navigate to <a href="http://stackoverflow.com">StackOverflow</a></p> </body> </html> 

我只是试过这个,它解决了这个问题:创build一个sessionStorage对象,当用户closures浏览器时会被销毁。 我们可以检查sessionStorage对象,以查找用户是否closures了浏览器或刷新了页面(sessionStorage对象不会在页面刷新时被销毁)。

  $(window).bind('unload', function () { if (/Firefox[\/\s](\d+)/.test(navigator.userAgent) && new Number(RegExp.$1) >= 4) { console.log('firefox delete'); var data = { async: false }; endSession(data); return null; } else { console.log('NON-firefox delete'); var data = { async: true }; endSession(data); return null; } }); function endSession(data) { var id = 0 if (window) { // closeed id=1 } $.ajax({ url: '/api/commonAPI/'+id+'?Action=ForceEndSession', type: "get", data: {}, async: data.async, success: function () { console.log('Forced End Session'); } }); } 

如果(窗口)使用来确定是否closures或只是重新加载。 为我工作。

今天我遇到了同样的问题,并find了一个我想与你分享的解决scheme。

在思考什么可以帮助辨别刷新和closures之间时,我想起了cookies。 我记得设置一个没有明确的截止date的cookie,只会将它提供给当前会话。 在浏览器closures之前,当前会话显然是有效的。 这不包括closures选项卡,但我的问题是有关用户身份validation,我不想注销用户只closures了一个选项卡(我认为这是ASPXAUTH cookie的ASP.NET相同的方法)。

所以,当用户login并在页面加载时检查它时,我在document.cookies集合中添加了一个简单的cookie:如果cookie仍然存在,那么刷新或重新打开的选项卡并保存用户数据(如果cookie不存在)过期以便清除用户数据(与显式注销相同)。

希望这种方法对别人有用!

我以前的解决scheme在IE中为我工作。 对于IE以外的浏览器,window.event是未定义的,因为“事件”在IE中是全局定义的,与其他浏览器不同。 在其他浏览器的情况下,您需要提供事件作为参数。 此外clientX没有为Firefox定义,我们应该使用pageX。

尝试这样的东西….应该为IE和Firefox的工作…

 <html> <body> <script type="text/javascript"> window.onunload = function(e) { // Firefox || IE e = e || window.event; var y = e.pageY || e.clientY; if(y < 0) alert("Window closed"); else alert("Window refreshed"); } </script> </body> </html> 
 <html> <body onunload="doUnload()"> <script> function doUnload(){ if (window.event.clientX < 0 && window.event.clientY < 0){ alert("Window closed"); } else{ alert("Window refreshed"); } } </script> </body> </html>