页面离开时删除聊天室用户,刷新不执行删除的JS解决方案
问题
我正在搭建一个多房间的聊天室网站,希望在用户离开页面(而非刷新页面)时将其从数据库中删除。我了解到常见方案是使用sessionStorage,但该方案在用户不离开页面仅切换房间时会保留对应值。
目前我通过以下代码在用户加入房间时将其添加至数据库:
if (!window.performance.getEntriesByType('navigation').map((nav) => nav.type).includes('reload')) { addUserToDatabase(); }
现在需要实现类似如下逻辑的删除功能:
window.onbeforeunload = function() { if (/* Is not about to reload */){ deleteUserFromDatabase(); } }
求可行的Javascript/JQuery解决方案。
解决方案
方法1:页面可见性+定时器区分刷新/关闭
刷新页面时,浏览器会先把页面设为隐藏状态,之后再重新显示;而关闭页面只会触发隐藏。利用这个特性配合定时器判断:
let isReloading = false; // 监听页面可见性变化 document.addEventListener('visibilitychange', () => { if (document.visibilityState === 'visible') { isReloading = true; } }); window.addEventListener('beforeunload', async () => { // 延迟100ms等待visibility状态更新 await new Promise(resolve => setTimeout(resolve, 100)); if (!isReloading) { deleteUserFromDatabase(); } });
方法2:sessionStorage临时标记刷新状态
在页面卸载前设置一个刷新标记,页面重新加载时清除该标记。如果是关闭页面,这个标记不会被清除,但定时器会完成执行:
// 页面加载时清除刷新标记 window.addEventListener('load', () => { sessionStorage.removeItem('isRefreshing'); }); window.addEventListener('beforeunload', () => { sessionStorage.setItem('isRefreshing', 'true'); // 延迟执行删除,刷新时页面会重启,定时器会被终止 setTimeout(() => { // 检查标记是否存在,不存在说明是关闭页面 if (!sessionStorage.getItem('isRefreshing')) { deleteUserFromDatabase(); } }, 500); });
方法3:用现代Navigation API直接判断
现代浏览器支持navigation.type属性,可直接获取导航类型,兼容性覆盖Chrome 80+、Firefox 85+:
window.addEventListener('beforeunload', () => { // navigation.type为'reload'时是刷新,否则执行删除 if (navigation.type !== 'reload') { deleteUserFromDatabase(); } });
额外提示:切换房间的处理
用户不刷新页面切换房间时,要主动调用删除当前房间用户的逻辑,再添加到新房间,避免sessionStorage残留问题:
// 示例切换房间函数 function switchRoom(newRoomId) { // 删除当前房间的用户记录 deleteUserFromDatabase(currentRoomId, userId); // 添加到新房间 addUserToDatabase(newRoomId, userId); // 更新当前房间ID currentRoomId = newRoomId; }
内容的提问来源于stack exchange,提问作者MRVN
相关产品推荐
相关产品推荐

