前端removeEventListener 移除监听事件

  • Post author:
  • Post category:其他




解决 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() 取消监听事件失效原因



版权声明:本文为coising原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。