在刷新和关闭浏览器操作之间进行标识

ash*_*att 39 javascript browser

当我们刷新页面(F5或浏览器中的图标)时,它将首先触发ONUNLOAD事件.当我们关闭浏览器(X右上图标)时,它将触发ONUNLOAD事件.现在,当触发ONUNLOAD事件时,无法区分刷新页面或关闭浏览器.如果你有任何解决方案,那就给我.

Jul*_*egg 45

有一个解决方案.

我希望在关闭选项卡或浏览器窗口时断开服务器上的用户连接,但是在重新加载页面时不要断开连接(您可能希望区分重新加载/关闭事件以用于其他目的,但您可以从我的解决方案中受益).基于HTML5的本地存储和客户端/服务器AJAX通信,我最终得到了以下过程:

  1. 在您的页面上,添加onunloadwindow以下处理程序(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
    }
    
    Run Code Online (Sandbox Code Playgroud)
  2. 您的网页上,添加一个onloadbody下面的处理程序(伪的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)
            }
        }
    } 
    
    Run Code Online (Sandbox Code Playgroud)
  3. 在服务器上,收集列表中的断开连接请求,并设置一个定时器线程,定期检查列表(我每隔20秒使用一次).一旦断开请求超时(即5秒消失),断开用户与服务器的连接.如果在此期间接收到断开连接请求取消,则从列表中移除相应的断开连接请求,以便不断开用户的连接.

如果要区分选项卡/窗口关闭事件和后续链接或提交的表单,则此方法也适用.您只需将两个事件处理程序放在包含链接和表单的每个页面上以及每个链接/表单登录页面上.

请注意,我使用unload事件而不是beforeUnload事件来正确管理附件链接:当用户单击指向附件的链接(例如PDF文件)时,将beforeUnload调度事件,然后引发打开/保存弹出窗口,并且仅此而已(浏览器不会更改显示的页面,也不会调度unload事件).如果我正在使用该beforeUnload事件(就像我之前所做的那样),那么在没有事件时我会检测到页面更改.

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

基于它的其他方法event.clientY不可靠,因为当单击重新加载或选项卡/窗口关闭按钮时此值为负,而当使用键盘快捷键重新加载(例如F5,Ctrl-R,...)和窗口关闭时,该值为正(例如Alt-F4).依赖事件X位置也不可靠,因为按钮没有放在每个浏览器上的相同位置(例如左侧的关闭按钮).

  • 我使用`sessionStorage`而不是`localStorage`,因为你只是跟踪重新加载,没有理由坚持它. (5认同)
  • @RajabShakirov这个答案不适用于在卸载事件期间检测刷新. (3认同)

Moi*_*nty 12

也许有人仍在寻找答案......

您可以使用SessionStorage来实现!SessionStorage 不会在页面重新加载时清除,而是在页面关闭时清除。因此基本上您可以在加载页面时设置键/值对,但在此之前您检查键/值对是否存在。如果它确实存在,则意味着页面已重新加载,如果不存在,则意味着用户第一次打开该页面或在新选项卡中打开该页面。

if (sessionStorage.getItem('reloaded') != null) {
    console.log('page was reloaded');
} else {
    console.log('page was not reloaded');
}

sessionStorage.setItem('reloaded', 'yes');
Run Code Online (Sandbox Code Playgroud)

通过这种方式,您可以doStuff()处理onunload事件(用户离开页面),以及otherStuff()是否设置了键/值对(用户重新加载页面)。


Wal*_*sby 6

不幸的是,正如这里的一些答案所示,检查事件的clientY/ pageY值并不是确定unload事件是否因用户关闭页面而被触发的可靠方法.

单击浏览器的关闭按钮时原因clientY/ pageY是否定是因为关闭按钮位于文档顶部上方(即像素0上方),但是重新加载按钮也是如此,这意味着单击重新加载按钮也会导致否定clientY/的值pageY.

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


Rea*_*ed. -11

<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>
Run Code Online (Sandbox Code Playgroud)