在选项卡或浏览器窗口关闭时运行代码,但在页面重新加载时不运行代码

Run code when the tab or browser windows is closed, but not on page reload

提问人:Osama Ameer 提问时间:8/31/2023 最后编辑:Richard EbelingOsama Ameer 更新时间:8/31/2023 访问量:225

问:

我想在用户关闭选项卡或窗口时运行 javascript 函数,但如果用户只是刷新页面,则不行。

我尝试了该事件的事件处理程序,但它也会在页面重新加载时触发。 有没有办法忽略事件的页面重新加载,或者是否有其他事件可以解决我的问题?beforeunloadbeforeunload

这是我当前的代码:

window.addEventListener("beforeunload", (event) => {
    event.preventDefault();
    // Remove this tab from sessionStorage
    sessionStorage.removeItem(tabKey);

    // Notify other tabs to close this tab
    const activeTabs = JSON.parse(localStorage.getItem(tabKey)) || [];
    const updatedTabs = activeTabs.filter((id) => id !== tabId);

    if (updatedTabs?.length === 0) {
        // All tabs are closed, execute your code
        const id = events.getIdentifier();
        let URL =
            API_URL +
            "chat/change-status?url=" +
            FIREBASE_FUNCTIONS_URL +
            "&id=" +
            id +
            "&status=" +
            Visitor_status.inactive +
            "&chat_status=" +
            chat_status.no_action;
        fetch(URL, {
            keepalive: true,
        });
    }
});
JavaScript 事件 dom-events 页面刷新 onbeforeunload

评论

0赞 epascarello 8/31/2023
没有真正的方法可以知道其中的区别......关于这个主题的数以千计的问题,都用黑客方法来解决它,但都行不通。您发出的获取请求将处于浏览器退出的竞争状态,因此您可能会或可能不会得到它。

答:

1赞 Bhavy Ladani 8/31/2023 #1
  • beforeunload 事件通常在刷新时触发 页面以及关闭选项卡或浏览器时。在现代浏览器中, 没有内置的方法来区分页面刷新和 选项卡/浏览器在 beforeUnload 事件中关闭。

但是,有一个解决方法:

  • 侦听 visibilitychange 事件。如果页面的可见性 更改为 hided(在刷新或选项卡/浏览器之前发生) close),设置一个标志。在 beforeunload 事件中,检查标志 已设置。如果有,则该操作可能是刷新。如果它 没有,行动可能已经结束了。

     let isTabHidden = false;
    
    // Detect when the visibility of the page changes
     document.addEventListener('visibilitychange', () => {
     if (document.visibilityState === 'hidden') {
         isTabHidden = true;
     }
    });
    
     window.addEventListener("beforeunload", (event) => {
     // Check if the tab's visibility has changed to hidden
     if (isTabHidden) {
     return; 
     }
    
     // ... (The rest of your code remains unchanged.)
    });
    

评论

0赞 Osama Ameer 8/31/2023
不从这里返回,而是其他代码没有执行。
0赞 Bhavy Ladani 8/31/2023
你能告诉我你的用例是什么吗?就像您可以将某些内容存储在本地存储中并访问它一样。刷新时,您可以再次将其恢复。但是在关闭选项卡后,它就会消失。所以这可能是一个用例。
0赞 Osama Ameer 8/31/2023
基本上,我的用例是我有聊天应用程序,从访问者的角度来看,我希望如果访问者关闭选项卡/窗口,那么我必须运行 API,基本上将该访问者的状态从活动更改为非活动,但是当页面刷新时,该功能也会触发这就是问题所在,这就是为什么我只需要关闭选项卡/窗口而不是刷新时的事件。
0赞 Bhavy Ladani 8/31/2023
beforeUnload 事件不区分刷新和关闭。而且,如果您为此编写任何 hack,我不确定这是否适用于所有浏览器,因为这可能会失败并且不合法。
0赞 Heiko Theißen 8/31/2023
将状态更改为 inactive onbeforeunload,并在页面(重新)加载后更改为 active。更好的是,让页面每分钟左右“ping”一次服务器,如果没有更多的ping,则将状态更改为非活动状态。