From 91b569ffd3ca62d3d846c0b17e63f4ddedc9c7bb Mon Sep 17 00:00:00 2001 From: lkddi Date: Sun, 1 Mar 2026 00:18:46 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=EF=BC=9A=E7=A6=BB=E5=BC=80?= =?UTF-8?q?=E6=8C=89=E9=92=AE=20confirm=20=E5=BC=B9=E7=AA=97=E5=9C=A8=20Ch?= =?UTF-8?q?rome=20=E9=97=AA=E7=83=81=E6=B6=88=E5=A4=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 将 beforeunload 改为 pagehide 事件: - pagehide 在页面关闭/刷新时触发,但不会弹原生「离开网站」确认框 - 与原生 confirm() 不产生冲突,Chrome/Edge 行为一致 - leaveRoom() 设 _manualLeave 标记,pagehide 里不重复发 beacon --- resources/views/chat/partials/scripts.blade.php | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/resources/views/chat/partials/scripts.blade.php b/resources/views/chat/partials/scripts.blade.php index 7f1acdb..5485efd 100644 --- a/resources/views/chat/partials/scripts.blade.php +++ b/resources/views/chat/partials/scripts.blade.php @@ -951,8 +951,8 @@ // ── 退出房间 ───────────────────────────────────── async function leaveRoom() { - // 主动移除 beforeunload 监听,防止 Chrome 触发"离开网站?"原生弹窗 - window.removeEventListener('beforeunload', sendLeaveBeacon); + // 标记主动离开,pagehide 里不重复发 beacon + window._manualLeave = true; clearTimeout(visibilityTimer); try { @@ -975,9 +975,14 @@ } + // ── 关闭/离开页面时自动调用 leave,结算勤务时长 ────────────────────── // 使用 sendBeacon 确保浏览器关闭时请求也能发出(比 fetch 更可靠) + // 注意:用 pagehide 而非 beforeunload,避免 Chrome 触发原生「离开网站」确认框 function sendLeaveBeacon() { + if (window._manualLeave) { + return; + } // 主动调用 leaveRoom() 时不重复发 const csrfToken = document.querySelector('meta[name="csrf-token"]')?.getAttribute('content'); if (!csrfToken || !window.chatContext?.leaveUrl) { return; @@ -987,8 +992,8 @@ navigator.sendBeacon(window.chatContext.leaveUrl, data); } - // beforeunload:关闭标签/浏览器/刷新 时触发 - window.addEventListener('beforeunload', sendLeaveBeacon); + // pagehide:页面关闭/浏览器关闭/刷新均触发,且不会弹原生确认框 + window.addEventListener('pagehide', sendLeaveBeacon); // visibilitychange:切换到后台标签超过30秒也结算(防止长期挂机不算时长) let visibilityTimer = null; @@ -1004,6 +1009,8 @@ }); + + // ── 掉线检测计数器 ── let heartbeatFailCount = 0; const MAX_HEARTBEAT_FAILS = 3;