如何检测生成的事件属于键盘事件、指针事件还是表单事件?
事件类型识别失效原因与最优方案
e instanceof KeyboardEvent失效的核心原因是该判断依赖事件对象与构造函数处于同一个全局上下文(即同一个window环境),如果你的应用涉及iframe嵌入、微前端沙箱隔离、跨文档事件传递等场景,事件对象所属的全局KeyboardEvent/MouseEvent构造函数和当前执行上下文的构造函数不相等,就会导致判断失败。
以下是三类可落地的解决方案,可根据你的应用场景选择:
方案1:使用Event.type属性做精确判断(最通用,无上下文依赖)
这是兼容性最高、不受上下文限制的方案,不同类型事件的type值是原生定义的固定字符串,可以直接匹配:
- 键盘事件:匹配
keydown、keyup、keypress三类type值 - 鼠标事件:匹配
mousedown、mouseup、click、dblclick、mousemove、mouseenter、mouseleave等 - 表单事件:匹配
input、change、submit、focus、blur、reset、select等
该方案尤其适合你的事件录制回放场景,匹配到对应type后可以直接关联对应的录制、回放处理逻辑,额外性能开销最低。
示例代码:
function getEventType(e) { // 键盘事件判断 if (['keydown', 'keyup', 'keypress'].includes(e.type)) { return 'keyboard' } // 鼠标事件判断 if (['mousedown', 'mouseup', 'click', 'dblclick', 'mousemove', 'mouseenter', 'mouseleave', 'contextmenu'].includes(e.type)) { return 'mouse' } // 表单事件判断 if (['input', 'change', 'submit', 'focus', 'blur', 'reset', 'select'].includes(e.type)) { return 'form' } return 'other' }
方案2:使用Object.prototype.toString.call(e)做类型校验(适合跨上下文的构造函数判断)
如果需要直接校验事件对象的内置类型,不需要逐个匹配type值,可以用该方法,它会返回对象的内部类名,不受上下文影响:
示例代码:
const eventClass = Object.prototype.toString.call(e) if (eventClass === '[object KeyboardEvent]') { // 判定为键盘事件 } else if (eventClass === '[object MouseEvent]') { // 判定为鼠标事件 } else if (['[object InputEvent]', '[object FocusEvent]', '[object SubmitEvent]'].includes(eventClass)) { // 判定为表单相关事件 }
方案3:兼容多上下文的instanceof判断(适合确定有跨上下文场景的情况)
如果一定要用instanceof的判断逻辑,可以主动获取事件对象所属全局的构造函数进行判断:
function isKeyboardEvent(e) { const eventWindow = e.view || window return e instanceof eventWindow.KeyboardEvent }
这个方案的原理是Event.view属性会返回事件所属的window对象,直接用该上下文下的构造函数做instanceof判断即可解决跨上下文失效的问题。
内容的提问来源于stack exchange,提问作者زوہیب خان
相关产品推荐
相关产品推荐

