鼠标事件
click 事件
触发条件
-
鼠标左键按下并释放在同一元素上
-
触摸设备上手指触摸并释放
-
键盘回车或空格键(在可聚焦元素上)
-
调用元素的
.click()方法
当用户点击元素时触发:
document.getElementById("myButton").addEventListener("click", function() {
alert("按钮被点击了!");
});
dblclick 事件
触发流程
双击完整事件流:
1. 第一次点击:
mousedown → mouseup → click
2. 第二次点击(在时间窗口内):
mousedown → mouseup → click → dblclick
注意:双击会触发两次完整的单击流程
双击元素时触发:
document.getElementById("myBox").addEventListener("dblclick", function() {
this.style.backgroundColor = "red";
});
mouseover/mouseout 事件
mouseover: 鼠标指针进入元素或其子元素时触发
mouseout: 鼠标指针离开元素或其子元素时触发
关键特性:
1. 支持事件冒泡
2. 涉及子元素时会频繁触发
3. 适合需要精细控制的悬停交互
鼠标移入/移出元素时触发:
document.getElementById("hoverArea").addEventListener("mouseover", function() {
this.textContent = "鼠标进来了";
});
document.getElementById("hoverArea").addEventListener("mouseout", function() {
this.textContent = "鼠标出去了";
});
键盘事件
keydown 事件
keydown: 按下任意键盘键时触发(包括功能键、组合键)
触发流程:
1. 物理按下键盘键
2. keydown 事件触发
3. 如果产生字符:keypress 事件(已废弃)
4. 释放按键:keyup 事件
重复触发:
如果按住不放,keydown 会以系统重复速率连续触发
(可通过操作系统设置调整重复延迟和速率)
按下键盘任意键时触发:
document.addEventListener("keydown", function(event) {
console.log("按下的键码是: " + event.keyCode);
});
keyup 事件
释放键盘按键时触发:
document.getElementById("textInput").addEventListener("keyup", function(event) {
console.log("输入的内容: " + this.value);
});
表单事件
submit 事件
submit 事件的发途径:
1. 用户点击 type="submit" 的按钮或 input
2. 用户点击 type="image" 的图片提交按钮
3. 在表单内按 Enter 键(单行输入时)
4. 调用 form.submit() 方法(不会触发 submit 事件!)
5. 调用 form.requestSubmit() 方法(会触发 submit 事件)
关键区别:
- form.submit() → 直接提交,不触发事件
- form.requestSubmit() → 模拟用户提交,触发事件
表单提交时触发:
document.getElementById("myForm").addEventListener("submit", function(event) {
event.preventDefault();
alert("表单已阻止默认提交!");
});
change 事件
change 事件的触发时机取决于表单元素类型:
文本输入类(input type="text|email|password|search|tel|url"):
1. 值发生变化
2. 元素失去焦点(blur)后触发
选择类(input type="checkbox|radio"):
1. 选中状态改变时立即触发
2. 点击或切换时立即触发
下拉选择(select):
1. 选择选项改变时立即触发
2. 无论是通过鼠标、键盘还是程序修改
文件选择(input type="file"):
1. 用户选择文件后立即触发
2. 文件列表发生变化时触发
范围选择(input type="range"):
1. 值改变并释放鼠标时触发
2. 拖动过程中不触发,释放时才触发
日期时间类(input type="date|time|datetime-local|month|week"):
1. 选择新值后立即触发
2. 通常是确认选择后触发
关键特性:change 事件不一定实时触发,有延迟性
表单元素值改变时触发(如输入框、下拉框):
document.getElementById("colorSelect").addEventListener("change", function() {
console.log("选中的颜色: " + this.value);
});
focus/blur 事件
元素获得/失去焦点时触发:
document.getElementById("emailInput").addEventListener("focus", function() {
this.placeholder = "";
});
document.getElementById("emailInput").addEventListener("blur", function() {
this.placeholder = "请输入邮箱";
});
窗口事件
load 事件
页面或资源加载完成时触发:
window.addEventListener("load", function() {
console.log("页面加载完毕");
});
resize 事件
窗口大小改变时触发:
window.addEventListener("resize", function() {
console.log("窗口尺寸: " + window.innerWidth + "x" + window.innerHeight);
});
scroll 事件
滚动页面时触发:
window.addEventListener("scroll", function() {
console.log("当前滚动位置: " + window.pageYOffset);
});
触摸事件(移动端)
touchstart 事件
手指触摸屏幕时触发:
document.getElementById("touchArea").addEventListener("touchstart", function() {
this.style.backgroundColor = "blue";
});
touchend 事件
手指离开屏幕时触发:
document.getElementById("touchArea").addEventListener("touchend", function() {
this.style.backgroundColor = "white";
});
自定义事件
通过 CustomEvent 创建和触发自定义事件:
const event = new CustomEvent("myEvent", {
detail: { message: "这是自定义数据" }
});
document.addEventListener("myEvent", function(e) {
console.log(e.detail.message); // 输出:这是自定义数据
});
// 触发事件
document.dispatchEvent(event);
事件是 JavaScript 实现交互的核心机制,它连接了用户操作、浏览器行为与脚本逻辑。本文将系统梳理事件分类、深入解析事件机制、补充高阶用法,并结合开发实践给出优化方案,帮助开发者编写更健壮、高效的交互代码。
一、 核心事件分类及详细说明
JavaScript 事件覆盖了用户交互、资源加载、状态变化等多个维度,按触发场景可分为以下大类,部分事件补充了适用场景与使用细节:
1. 鼠标事件
鼠标事件是桌面端交互的基础,需重点区分冒泡与非冒泡 、元素自身与子元素触发 的差异。

2. 键盘事件
键盘事件用于捕获键盘操作,需注意事件触发顺序与键值判断逻辑。

关键属性:
key:返回按键的名称(如Enter、a)code:返回按键的物理位置(如KeyA、Enter)ctrlKey/shiftKey/altKey:判断是否同时按下修饰键
3. 表单事件
表单事件聚焦于表单元素的状态变化,是处理用户输入的核心

4. 窗口 / 文档事件
这类事件与浏览器窗口、文档加载状态强相关,是控制页面生命周期的关键。

5. 拖放事件
拖放事件实现元素的拖拽交互,需配合 draggable="true" 属性使用。

二、 事件机制深度解析
要掌握事件处理,必须理解事件流、事件对象、事件委托这三大核心概念。
1. 事件流的三个阶段
事件流描述了事件在 DOM 树中的传播路径,分为三个阶段,顺序不可逆:
-
捕获阶段(Capture Phase)
- 顺序:从
window向下传播到目标元素的父元素 - 触发时机:事件到达目标元素之前
- 开启方式:
addEventListener第三个参数设为true
- 顺序:从
-
目标阶段(Target Phase)
- 顺序:事件到达实际触发的元素
- 触发时机:捕获阶段结束后,冒泡阶段开始前
- 特点:此时
event.eventPhase === 2,事件处理顺序由绑定顺序决定
-
冒泡阶段(Bubble Phase)
- 顺序:从目标元素向上传播到
window - 触发时机:目标阶段结束后
- 特点:
addEventListener默认在该阶段触发(第三个参数为false)
- 顺序:从目标元素向上传播到
关键方法:
event.stopPropagation():阻止事件继续传播(捕获 / 冒泡)event.stopImmediatePropagation():阻止事件传播 + 阻止当前元素后续的监听器执行
2. 事件对象(Event)核心属性
事件对象是事件处理函数的唯一参数,包含了事件的所有关键信息,补充高频属性如下:

3. 事件委托(Event Delegation)
核心原理 :利用事件冒泡机制,在父元素上绑定一个监听器,处理所有子元素的事件。适用场景:
-
动态添加的子元素(如列表新增项)
-
大量同类子元素(如表格单元格)
-
优势:
-
减少事件监听器数量,降低内存占用
-
无需为动态元素重复绑定事件
-
简化代码维护
二、 框架中的事件处理差异
在 React、Vue 等框架中,事件系统基于原生事件封装,存在以下差异:
- React 合成事件
- 所有事件绑定到
document上,通过事件委托实现 - 需使用
e.nativeEvent获取原生事件对象 - 组件卸载时自动移除监听器
- 所有事件绑定到
- Vue 事件
- 支持原生事件和自定义事件(
$emit/v-on) - 自定义事件不冒泡,需使用
.native修饰符监听原生事件
- 支持原生事件和自定义事件(
- Angular 事件
- 使用
(event)语法绑定,支持事件过滤 - 内置
HostListener装饰器监听宿主元素事件
- 使用
三、 事件调试与监控技巧
- 浏览器开发者工具
- Elements → Event Listeners:查看元素绑定的所有监听器
- Sources → Event Listener Breakpoints:按事件类型打断点
- 性能监控
- 使用
Performance面板录制事件触发过程,分析耗时 - 监控高频事件触发频率,避免过度渲染
- 使用
- 错误捕获
- 使用
window.onerror捕获事件处理函数中的运行时错误 - 使用
window.addEventListener('unhandledrejection')捕获 Promise 错误
- 使用
总结
JavaScript 事件是前端交互的基石,掌握事件分类、事件流机制和优化方案,是编写高性能、可维护代码的关键。开发中需结合业务场景,合理选择事件类型,善用事件委托和节流防抖,同时兼顾兼容性与无障碍访问,才能构建出优质的交互体验。