|
@@ -2311,6 +2311,16 @@ const openChoiceQuestionDetail = (index:number) => {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+const handlePageUnload = () => {
|
|
|
|
|
+ if (isCreator.value && timerIndicator.value.visible) {
|
|
|
|
|
+ sendMessage({ type: 'timer_stop', courseid: props.courseid })
|
|
|
|
|
+ }
|
|
|
|
|
+ // 创建老师刷新/关闭页面时,清空激光笔共享状态
|
|
|
|
|
+ if (isCreator.value) {
|
|
|
|
|
+ clearLaserState()
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
onMounted(() => {
|
|
onMounted(() => {
|
|
|
document.addEventListener('keydown', handleKeydown)
|
|
document.addEventListener('keydown', handleKeydown)
|
|
|
|
|
|
|
@@ -2388,15 +2398,32 @@ onMounted(() => {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// 创建人离开页面时,广播停止计时
|
|
// 创建人离开页面时,广播停止计时
|
|
|
- window.addEventListener('beforeunload', () => {
|
|
|
|
|
- if (isCreator.value && timerIndicator.value.visible) {
|
|
|
|
|
- sendMessage({ type: 'timer_stop', courseid: props.courseid })
|
|
|
|
|
- }
|
|
|
|
|
- // 创建老师刷新/关闭页面时,清空激光笔共享状态
|
|
|
|
|
- if (isCreator.value) {
|
|
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ // beforeunload 事件(页面刷新或关闭)
|
|
|
|
|
+ window.addEventListener('beforeunload', handlePageUnload)
|
|
|
|
|
+
|
|
|
|
|
+ // visibilitychange 事件(适用于 iframe 嵌套场景,当外层页面返回时触发)
|
|
|
|
|
+ const handleVisibilityChange = () => {
|
|
|
|
|
+ if (document.hidden && isCreator.value) {
|
|
|
|
|
+ // 页面被隐藏时,清空激光笔状态
|
|
|
clearLaserState()
|
|
clearLaserState()
|
|
|
|
|
+ if (timerIndicator.value.visible) {
|
|
|
|
|
+ sendMessage({ type: 'timer_stop', courseid: props.courseid })
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
- })
|
|
|
|
|
|
|
+ }
|
|
|
|
|
+ document.addEventListener('visibilitychange', handleVisibilityChange)
|
|
|
|
|
+
|
|
|
|
|
+ // pagehide 事件(作为补充,某些浏览器中比 beforeunload 更可靠)
|
|
|
|
|
+ window.addEventListener('pagehide', handlePageUnload)
|
|
|
|
|
+
|
|
|
|
|
+ // 存储清理函数,方便在 onUnmounted 中移除
|
|
|
|
|
+ ;(window as any).__pptistStudentUnloadHandlers = {
|
|
|
|
|
+ beforeunload: handlePageUnload,
|
|
|
|
|
+ visibilitychange: handleVisibilityChange,
|
|
|
|
|
+ pagehide: handlePageUnload
|
|
|
|
|
+ }
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
@@ -2422,6 +2449,15 @@ onUnmounted(() => {
|
|
|
providerSocket.value = null
|
|
providerSocket.value = null
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ // 清理页面卸载相关的事件监听器
|
|
|
|
|
+ if ((window as any).__pptistStudentUnloadHandlers) {
|
|
|
|
|
+ const handlers = (window as any).__pptistStudentUnloadHandlers
|
|
|
|
|
+ window.removeEventListener('beforeunload', handlers.beforeunload)
|
|
|
|
|
+ document.removeEventListener('visibilitychange', handlers.visibilitychange)
|
|
|
|
|
+ window.removeEventListener('pagehide', handlers.pagehide)
|
|
|
|
|
+ delete (window as any).__pptistStudentUnloadHandlers
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
// 清理window上的引用
|
|
// 清理window上的引用
|
|
|
if ((window as any).PPTistStudent) {
|
|
if ((window as any).PPTistStudent) {
|
|
|
delete (window as any).PPTistStudent
|
|
delete (window as any).PPTistStudent
|
|
@@ -2431,6 +2467,8 @@ onUnmounted(() => {
|
|
|
clearInterval(timerInterval.value)
|
|
clearInterval(timerInterval.value)
|
|
|
timerInterval.value = null
|
|
timerInterval.value = null
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+ handlePageUnload()
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
// 手动重连
|
|
// 手动重连
|