前端removeEventListener 移除监听事件

文章讨论了在JavaScript中使用`visibilitychange`事件监听页面可见性变化,以及在`useEffect`中正确添加和移除事件监听器的技巧。当用户切屏时,会触发提醒和计数,多次切屏将结束考试。在组件卸载或特定条件满足时,通过`removeEventListener`停止监听以避免内存泄漏。文章强调了添加和移除事件处理程序需使用相同的函数引用以确保生效。
摘要由CSDN通过智能技术生成

解决 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')
}

注意事项

  1. 有 addEventListener,则有 removeEventListener,remove 写在 rerun 函数里
  2. 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() 取消监听事件失效原因

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值