修复:离开按钮 confirm 弹窗在 Chrome 闪烁消失
将 beforeunload 改为 pagehide 事件: - pagehide 在页面关闭/刷新时触发,但不会弹原生「离开网站」确认框 - 与原生 confirm() 不产生冲突,Chrome/Edge 行为一致 - leaveRoom() 设 _manualLeave 标记,pagehide 里不重复发 beacon
This commit is contained in:
@@ -951,8 +951,8 @@
|
|||||||
|
|
||||||
// ── 退出房间 ─────────────────────────────────────
|
// ── 退出房间 ─────────────────────────────────────
|
||||||
async function leaveRoom() {
|
async function leaveRoom() {
|
||||||
// 主动移除 beforeunload 监听,防止 Chrome 触发"离开网站?"原生弹窗
|
// 标记主动离开,pagehide 里不重复发 beacon
|
||||||
window.removeEventListener('beforeunload', sendLeaveBeacon);
|
window._manualLeave = true;
|
||||||
clearTimeout(visibilityTimer);
|
clearTimeout(visibilityTimer);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -975,9 +975,14 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ── 关闭/离开页面时自动调用 leave,结算勤务时长 ──────────────────────
|
// ── 关闭/离开页面时自动调用 leave,结算勤务时长 ──────────────────────
|
||||||
// 使用 sendBeacon 确保浏览器关闭时请求也能发出(比 fetch 更可靠)
|
// 使用 sendBeacon 确保浏览器关闭时请求也能发出(比 fetch 更可靠)
|
||||||
|
// 注意:用 pagehide 而非 beforeunload,避免 Chrome 触发原生「离开网站」确认框
|
||||||
function sendLeaveBeacon() {
|
function sendLeaveBeacon() {
|
||||||
|
if (window._manualLeave) {
|
||||||
|
return;
|
||||||
|
} // 主动调用 leaveRoom() 时不重复发
|
||||||
const csrfToken = document.querySelector('meta[name="csrf-token"]')?.getAttribute('content');
|
const csrfToken = document.querySelector('meta[name="csrf-token"]')?.getAttribute('content');
|
||||||
if (!csrfToken || !window.chatContext?.leaveUrl) {
|
if (!csrfToken || !window.chatContext?.leaveUrl) {
|
||||||
return;
|
return;
|
||||||
@@ -987,8 +992,8 @@
|
|||||||
navigator.sendBeacon(window.chatContext.leaveUrl, data);
|
navigator.sendBeacon(window.chatContext.leaveUrl, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
// beforeunload:关闭标签/浏览器/刷新 时触发
|
// pagehide:页面关闭/浏览器关闭/刷新均触发,且不会弹原生确认框
|
||||||
window.addEventListener('beforeunload', sendLeaveBeacon);
|
window.addEventListener('pagehide', sendLeaveBeacon);
|
||||||
|
|
||||||
// visibilitychange:切换到后台标签超过30秒也结算(防止长期挂机不算时长)
|
// visibilitychange:切换到后台标签超过30秒也结算(防止长期挂机不算时长)
|
||||||
let visibilityTimer = null;
|
let visibilityTimer = null;
|
||||||
@@ -1004,6 +1009,8 @@
|
|||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ── 掉线检测计数器 ──
|
// ── 掉线检测计数器 ──
|
||||||
let heartbeatFailCount = 0;
|
let heartbeatFailCount = 0;
|
||||||
const MAX_HEARTBEAT_FAILS = 3;
|
const MAX_HEARTBEAT_FAILS = 3;
|
||||||
|
|||||||
Reference in New Issue
Block a user