Event对象是浏览器自动注入事件处理函数的第一个参数,用于描述事件类型、触发元素、坐标、按键等上下文信息;需注意target与currentTarget区别,异步使用需解构保存;传数据应使用CustomEvent的detail字段。
它不是你手动 new Event() 出来的(除非主动构造),而是事件触发时由浏览器注入到事件处理函数中的第一个参数。比如给按钮绑点击,addEventListener('click', handler),这个 handler 被调用时,浏览器会把一个 Event 实例作为第一个实参传进去。
它的核心作用是:描述「谁触发了什么事件、在哪儿触发、当时按了哪些键、鼠标在哪、是否被阻止默认行为」等上下文信息。
最常见写法就是直接在回调函数形参里声明它:
button.addEventListener('click', function(event) {
console.log(event.type); // 'click'
console.log(event.target); // 触发事件的 DOM 元素(可能是 button,也可能是它里面的 span)
console.log(event.currentTarget); // 绑定事件监听器的元素(这里是 button)
console.log(event.clientX, event.clientY); // 相对于视口的鼠标坐标
});
注意几个易错点:
event.target 和 event.currentTarget 不一定相同——事件冒泡时尤其容易混淆event,但不能用 this 指向 currentTarget,得靠 event.currentTarget
setTimeout 里再访问 event),那对象可能已被回收或属性失效,需提前解构保存原生 Event 构造器不支持传数据,要带 payload 得用 CustomEvent:
const myEvent = new CustomEvent('data-loaded', {
detail: { userId: 123, status: 'success' }
});
element.dispatchEvent(myEvent);
// 监听时:
element.addE
ventListener('data-loaded', function(event) {
console.log(event.detail.userId); // 123
});
关键点:
detail 是唯一允许传任意结构数据的字段,必须是对象(null 也行)CustomEvent 默认不可冒泡、不可取消,如需这些行为,得显式传 { bubbles: true, cancelable: true }
Event 构造器配 detail——它会忽略该字段,且不报错DOM 事件本质是冒泡/捕获机制,不是消息总线。想把信息从子组件“透传”到远端父组件,不能只靠原生事件链:
event.stopPropagation(),中断传递Event,event.nativeEvent 才是原始对象postMessage 或自定义通信协议,Event 对象本身无法跨线程序列化真正需要灵活传参时,优先考虑函数回调、状态管理或事件总线(如 mitt),而不是硬塞进 DOM Event。