当我们刷新页面(F5或浏览器中的图标)时,它将首先触发ONUNLOAD事件.当我们关闭浏览器(X右上图标)时,它将触发ONUNLOAD事件.现在,当触发ONUNLOAD事件时,无法区分刷新页面或关闭浏览器.如果你有任何解决方案,那就给我.
有一个解决方案.
我希望在关闭选项卡或浏览器窗口时断开服务器上的用户连接,但是在重新加载页面时不要断开连接(您可能希望区分重新加载/关闭事件以用于其他目的,但您可以从我的解决方案中受益).基于HTML5的本地存储和客户端/服务器AJAX通信,我最终得到了以下过程:
在您的页面上,添加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 }
您的网页上,添加一个onload
对body
下面的处理程序(伪的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) } } }
在服务器上,收集列表中的断开连接请求,并设置一个定时器线程,定期检查列表(我每隔20秒使用一次).一旦断开请求超时(即5秒消失),断开用户与服务器的连接.如果在此期间接收到断开连接请求取消,则从列表中移除相应的断开连接请求,以便不断开用户的连接.
如果要区分选项卡/窗口关闭事件和后续链接或提交的表单,则此方法也适用.您只需将两个事件处理程序放在包含链接和表单的每个页面上以及每个链接/表单登录页面上.
请注意,我使用unload
事件而不是beforeUnload
事件来正确管理附件链接:当用户单击指向附件的链接(例如PDF文件)时,将beforeUnload
调度事件,然后引发打开/保存弹出窗口,并且仅此而已(浏览器不会更改显示的页面,也不会调度unload
事件).如果我正在使用该beforeUnload
事件(就像我之前所做的那样),那么在没有事件时我会检测到页面更改.
这种方法仅限于支持HTML5本地存储的浏览器,因此您可能会使用旧版浏览器(如MSIE7)的特定方法.
基于它的其他方法event.clientY
不可靠,因为当单击重新加载或选项卡/窗口关闭按钮时此值为负,而当使用键盘快捷键重新加载(例如F5,Ctrl-R,...)和窗口关闭时,该值为正(例如Alt-F4).依赖事件X位置也不可靠,因为按钮没有放在每个浏览器上的相同位置(例如左侧的关闭按钮).
不幸的是,正如这里的一些答案所示,检查事件的clientY
/ pageY
值并不是确定unload
事件是否因用户关闭页面而被触发的可靠方法.
单击浏览器的关闭按钮时原因clientY
/ pageY
是否定是因为关闭按钮位于文档顶部上方(即像素0上方),但是重新加载按钮也是如此,这意味着单击重新加载按钮也会导致否定clientY
/的值pageY
.
沿着检查事件的x坐标的路径也是有问题的,因为浏览器关闭按钮并不总是在窗口的右侧(例如,它在OS X的左侧)并且因为窗口可以关闭关闭其标签或通过键盘.