一文教你掌握事件机制

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 文档解析完成但资源未加载完
相关推荐
样子201828 分钟前
Uniapp 之renderjs解决swiper+多个video卡顿问题
前端·javascript·css·uni-app·html
Nicholas6837 分钟前
flutterAppBar之SystemUiOverlayStyle源码解析(一)
前端
黑客飓风1 小时前
JavaScript 性能优化实战大纲
前端·javascript·性能优化
MobotStone2 小时前
你以为AI在思考?其实90%在搬砖!
ai编程
emojiwoo2 小时前
【前端基础知识系列六】React 项目基本框架及常见文件夹作用总结(图文版)
前端·react.js·前端框架
张人玉3 小时前
XML 序列化与操作详解笔记
xml·前端·笔记
杨荧3 小时前
基于Python的宠物服务管理系统 Python+Django+Vue.js
大数据·前端·vue.js·爬虫·python·信息可视化
Goboy3 小时前
消消乐游戏:Trae 轻松实现色彩缤纷的消除乐趣
ai编程·trae
Goboy3 小时前
纸牌接龙:Trae 轻松实现经典纸牌挑战
ai编程·trae
YeeWang4 小时前
🎉 Eficy 让你的 Cherry Studio 直接生成可预览的 React 页面
前端·javascript