一文教你掌握事件机制

JavaScript 的事件机制是前端交互的核心,它允许开发者监听用户行为(如点击、输入、滚动等)并作出响应。理解原生 JS 的事件模型对于写出高效、可维护的代码至关重要。

本文将从以下几个方面详细讲解 原生 JavaScript 的事件机制

一、什么是事件?

在浏览器中,事件(Event) 是当某些行为发生时由浏览器自动触发的通知。例如:

  • 用户点击按钮 → 触发 click 事件;
  • 鼠标移动到元素上 → 触发 mouseover 事件;
  • 表单提交 → 触发 submit 事件;

开发者可以通过编写"事件监听器"来响应这些事件。

二、绑定事件的方式

1. DOM 0 级事件处理(内联 / 属性式)

html 复制代码
<!-- HTML 内联 -->
<button onclick="sayHello()">点我</button>
js 复制代码
// JS 属性绑定
const btn = document.getElementById('btn');
btn.onclick = function() {
    alert('Hello');
};

⚠️ 缺点:

  • 只能绑定一个事件处理器;
  • 不利于代码分离;

2. DOM 2 级事件处理(推荐方式)

使用 addEventListener() 方法添加多个监听器,并支持捕获/冒泡阶段。

js 复制代码
btn.addEventListener('click', function(event) {
    console.log('按钮被点击了');
}, false);

参数说明:

参数 含义
'click' 事件类型(如 click、keydown、input 等)
function(event) 回调函数,接收事件对象
false 是否在捕获阶段执行,默认为 false(即冒泡阶段)

✅ 优点:

  • 支持多个监听器;
  • 支持捕获和冒泡;
  • 更加灵活、安全;

三、事件流的三个阶段

当你点击页面中的某个元素时,事件并不是直接触发一次,而是经历以下三个阶段:

1. 捕获阶段

事件从最外层 (如 windowdocument)向目标元素逐级传递。

css 复制代码
window → document → html → body → ... → target

在这个阶段,父级元素可以提前"感知"到事件即将到达目标。

2. 目标阶段

事件到达你真正点击的目标元素 。此时 event.target 被确定。

3. 冒泡阶段

事件从目标元素开始,向外层传播回根节点。

css 复制代码
target → ... → body → html → document → window

⚠️ 并非所有事件都会冒泡(如 focus, blur 就不会冒泡)。

四、useCapture 参数的作用

addEventListener() 的第三个参数控制监听器是在哪个阶段执行:

  • true:在捕获阶段执行;
  • false(默认):在冒泡阶段执行;
js 复制代码
document.getElementById('parent').addEventListener('click', () => {
    console.log('Parent');
}, true);

document.getElementById('child').addEventListener('click', () => {
    console.log('Child');
}, false);

点击 <div id="child"> 输出顺序:

复制代码
Parent 
Child 

五、事件对象(Event Object)

每个事件回调函数都会接收到一个事件对象(event),它包含了许多有用的信息:

js 复制代码
element.addEventListener('click', function(event) {
    console.log(event.type);        // 事件类型,如 'click'
    console.log(event.target);      // 触发事件的原始元素
    console.log(event.currentTarget); // 当前监听事件的元素(this)
    console.log(event.clientX, event.clientY); // 鼠标坐标
});

常用属性

属性 描述
type 事件类型
target 触发事件的真实元素
currentTarget 绑定监听器的元素(即 this
bubbles 该事件是否会冒泡
cancelable 是否可以阻止默认行为

六、阻止默认行为与事件传播

1. 阻止默认行为:preventDefault()

适用于链接跳转、表单提交等默认行为。

js 复制代码
form.addEventListener('submit', function(event) {
    event.preventDefault(); // 阻止表单提交
    console.log('表单未提交');
});

2. 阻止事件传播:stopPropagation()

阻止事件继续向上冒泡或向下捕获

js 复制代码
child.addEventListener('click', function(event) {
    event.stopPropagation();
    console.log('子元素被点击');
});

此时父元素的点击事件将不会被触发。


七、事件委托(Event Delegation)

由于事件会冒泡,我们可以将事件监听器放在父元素 上,统一处理子元素的事件,这就是事件委托

html 复制代码
<ul id="menu">
    <li>首页</li>
    <li>关于我们</li>
    <li>联系我们</li>
</ul>
js 复制代码
document.getElementById('menu').addEventListener('click', function(event) {
    if (event.target.tagName === 'LI') {
        console.log('你点击了:', event.target.innerText);
    }
});

✅ 优点:

  • 减少监听器数量
  • 动态添加的子元素也能响应事件
  • 提高性能

八、常见事件类型

事件类型 触发时机 事件类型 触发时机
click 鼠标点击或触屏点击 change input 元素失去焦点后内容改变
mousedown/mouseup 鼠标按下/释放 submit 表单提交
mousemove 鼠标移动 scroll 页面或元素滚动
keydown/keyup 键盘按键按下/释放 resize 窗口大小变化
input input 元素内容变化(实时) load 页面或资源加载完成
DOMContentLoaded HTML 文档解析完成但资源未加载完
相关推荐
AI大模型-小华38 分钟前
Codex 三方充值快速入门指南
java·前端·数据库·chatgpt·ai编程·codex·chatgpt pro
做前端的娜娜子3 小时前
同一链接实现 PC Web 与移动 H5 自适应
前端·掘金·金石计划
小帅不太帅3 小时前
架构没变、规模没变,DeepSeek V4 Flash 正式版凭什么暴涨 47 分?
前端·aigc·deepseek
jarvisuni3 小时前
DeepSeekFlash前端依旧拉垮,而且变慢了很多!
前端·javascript·算法
Tsonglew4 小时前
OpenWorker 代码解剖:一个 AI 同事"敢让它干活"的工程学
agent·ai编程
卷福同学5 小时前
AI编程出海第二步:验证关键词能否做站
前端·人工智能·后端
AI编程实验室5 小时前
大模型手搓文件对比工具(6):差异不用再手选
ai编程
赵庆明老师5 小时前
Vben精讲:21-详解web-antd:tsconfig.json
前端·json·vim
wc885 小时前
微软EDGE浏览器功能学习
前端·学习·edge