You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

报错e is undefined 递归事件处理函数的正确语法是什么?

错误原因

  • 你在keydown事件回调末尾主动调用了checkExit(),没有传入事件参数,所以函数执行时形参e为undefined,触发报错
  • 递归调用逻辑完全错误:键盘事件是浏览器触发的,不需要你主动循环调用回调函数,每次按键时浏览器会自动把事件对象作为参数传入回调执行
  • 额外问题:prevKeyCode变量没有提前声明,会默认挂到全局作用域,容易产生冲突;每次点击按钮激活时都会重复绑定keydown事件,会导致内存泄漏和逻辑异常

修正后的实现代码

// 把状态变量提到外部,避免每次点击重新初始化
let prevKeyCode = null;
// 提前定义退出检测函数
function exit(event) {
  const code = event.keyCode || event.which;
  const doubleEnter = (code == 13 && prevKeyCode == code);

  if (event.type == "click") {
    return true;
  } else if (event.type == 'keydown') {
    if (code == 27 || doubleEnter) {
      prevKeyCode = null;
      return true;
    } else if (code == 13) {
      prevKeyCode = 13;
    } else {
      prevKeyCode = code;
    }
    return false;
  }
  return false;
}

$("button#ul").on("click", function(event) {
  const button = $(this);
  button.toggleClass("active");
  
  // 先解绑之前可能存在的keydown事件,避免重复绑定
  $(document).off("keydown", handleKeydown);
  if (button.hasClass('active')) {
    // 绑定键盘事件
    $(document).on("keydown", handleKeydown);
  }

  // 键盘事件回调单独定义,方便绑定和解绑
  function handleKeydown(e) {
    if (exit(e) == true) {
      button.removeClass('active');
      $(document).off("keydown", handleKeydown);
    }
  }
});

改动说明

  • 移除了错误的主动递归调用逻辑,完全依靠浏览器事件触发执行回调
  • 提前声明prevKeyCode状态变量,避免隐式全局变量问题
  • 每次绑定keydown事件前先解绑旧事件,避免重复绑定导致的多次执行问题
  • 把键盘事件回调单独命名定义,方便精准解绑,避免误解绑其他同类型事件

内容的提问来源于stack exchange,提问作者the_indios

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 02:24:03