解决 removeEventListener 不生效问题
监听切屏代码
// 监听事件:'visibilitychange'
// 监听事件函数:
const ListenFun = () => {
if (document.hidden) {
// 失去焦点
postExamOut(Number(params.examId)).then(res => {
setCount(res)
})
if (countRef.current < 2 && timeDown.current !== 0) {
console.log(countRef.current, 'Count切屏小于3')
notification.open({
message: '切屏提醒',
description: `请勿切换屏幕,多次切换将强行结束考试!`,
duration: 5,
style: {
width: 600,
fontSize: 'larger',
fontWeight: 'bold'
}
})
}
} else if (document.visibilityState == 'visible') {
getExaminationContent(Number(params?.examId)).then(res => {
setTime(Number(res.residualTime))
timeDown.current = Number(res.residualTime)
})
}
}
// useEffect里监听,移除
useEffect(() => {
countRef.current = count
console.log(countRef.current, 'count赋值countRef.current')
if (countRef.current == maxCount) {
end(
'多次切屏' +
'diffTime:' +
diffTime.toString() +
',startTime:' +
paperName?.startTime?.toString() +
',duration:' +
paperName?.duration?.toString()
)
notification.open({
message: '考试结束通知',
description: '您已跳出本页多次,现为您结束本场笔试',
duration: 0
})
}
if (timeDown.current !== 0) {
console.log('exam inginging')
window.addEventListener('visibilitychange', ListenFun)
}
return () => {
console.log('remove')
window.removeEventListener('visibilitychange', ListenFun)
}
}, [count])
// 结束后取消监听
const end = async (endReason: string) => {
console.log('over')
await postExamAnswer(Number(params.examId), {
endReason: endReason,
isEnd: true,
answer: userAnswer.current.map(item => ({
questionNumber: item.questionNumber,
answer: item.userAnswer
}))
})
window.removeEventListener('visibilitychange', ListenFun)
timeDown.current = 0
clearInterval(countdownTimer.current)
// setAdviceOpen(true)
navigate(`${prefix}paperEnd/${Number(params?.examId)}`)
// localStorage.removeItem('examinee-token')
}
注意事项
- 有 addEventListener,则有 removeEventListener,remove 写在 rerun 函数里
- add remove 函数必须是同一个,所以可以提出来定义在外面
addEventListener removeEventListener 语法
element.addEventListener(type,handler,false/true)
type:事件类型
handler:事件执行触发的函数
false/true:false为冒泡/ture为捕获,参数是true,表示在捕获阶段调用事件处理程序;如果是false,表示在冒泡阶段调用事件处理程序。
事件捕获:父级元素先触发,子集元素后触发;
事件冒泡:子集元素先触发,父级元素后触发
element.removeEventListener(type,handler,false/true)
type:事件类型
handler:事件执行触发的函数
false/true:false为冒泡/ture为捕获,参数是true,表示在捕获阶段调用事件处理程序;如果是false,表示在冒泡阶段调用事件处理程序。
参考
JavaScript 前端监听事件移除案例
监听页面关闭-VUE
获取网页所有的监听事件类型方法
解决 removeEventListener 不生效
EventTarget.removeEventListener() 取消监听事件失效原因
版权声明:本文为coising原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。