全部学科
NodeJS全栈
nodejs
Python全栈
python
小程序首页
📅 2026-05-17 10 分钟 ✍️ juanwangdev

事件处理与事件流

事件机制是浏览器交互的基础,理解事件流模型对前端开发至关重要。

事件流模型

三阶段流程

HTML
捕获阶段 → 目标阶段 → 冒泡阶段
JavaScript
<div id="outer">
    <div id="inner">
        <button id="btn">点击</button>
    </div>
</div>

<script>
    // 捕获阶段(从外到内)
    document.addEventListener('click', () => console.log('document捕获'), true);
    outer.addEventListener('click', () => console.log('outer捕获'), true);
    inner.addEventListener('click', () => console.log('inner捕获'), true);

    // 冒泡阶段(从内到外)
    btn.addEventListener('click', () => console.log('btn冒泡'), false);
    inner.addEventListener('click', () => console.log('inner冒泡'), false);
    outer.addEventListener('click', () => console.log('outer冒泡'), false);
</script>

addEventListener参数

JavaScript
element.addEventListener(event, handler, useCapture);

// useCapture:
// true  - 捕获阶段触发
// false - 冒泡阶段触发(默认)

事件绑定方式

传统方式对比

JavaScript
// DOM0级(无法同时绑定多个)
btn.onclick = function() { };
btn.onclick = null;  // 解绑

// DOM2级(推荐)
btn.addEventListener('click', handler);
btn.removeEventListener('click', handler);
方式特点
onclick简单、只能一个处理函数
addEventListener可绑定多个、支持捕获

事件对象

常用属性

JavaScript
btn.addEventListener('click', (e) => {
    console.log(e.type);        // 'click' 事件类型
    console.log(e.target);      // 实际触发元素
    console.log(e.currentTarget); // 当前绑定元素
    console.log(e.clientX);     // 鼠标X坐标
    console.log(e.clientY);     // 鼠标Y坐标
    console.log(e.timeStamp);   // 时间戳
});

常用方法

JavaScript
btn.addEventListener('click', (e) => {
    e.preventDefault();   // 阻止默认行为
    e.stopPropagation();  // 阻止事件传播
    e.stopImmediatePropagation(); // 阻止后续监听器
});

阻止默认行为

JavaScript
// 阻止链接跳转
document.querySelector('a').addEventListener('click', (e) => {
    e.preventDefault();
});

// 阻止表单提交
document.querySelector('form').addEventListener('submit', (e) => {
    e.preventDefault();
});

// 阻止右键菜单
document.addEventListener('contextmenu', (e) => {
    e.preventDefault();
});

阻止事件传播

HTML
// 阻止冒泡
inner.addEventListener('click', (e) => {
    e.stopPropagation();
    // 事件不会传播到outer
});

// 阻止捕获和冒泡
inner.addEventListener('click', (e) => {
    e.stopImmediatePropagation();
    // 后续监听器也不会触发
});

事件委托

基本原理

JavaScript
<ul id="list">
    <li>项目1</li>
    <li>项目2</li>
    <li>项目3</li>
</ul>

<script>
    // 委托给父元素
    list.addEventListener('click', (e) => {
        if (e.target.tagName === 'LI') {
            console.log(e.target.textContent);
        }
    });

    // 动态添加元素同样生效
    list.innerHTML += '<li>项目4</li>';
</script>

事件委托优势

  • 减少内存占用(一个监听器)
  • 动态元素自动支持
  • 代码更简洁

判断目标元素

JavaScript
list.addEventListener('click', (e) => {
    // 精确匹配
    if (e.target.tagName === 'LI') { }

    // 类选择器匹配
    if (e.target.classList.contains('item')) { }

    // matches方法匹配
    if (e.target.matches('li.item')) { }

    // 获取最近匹配元素
    const li = e.target.closest('li');
});

常用事件类型

鼠标事件

事件触发时机
click单击
dblclick双击
mouseenter鼠标进入(不冒泡)
mouseleave鼠标离开(不冒泡)
mouseover鼠标进入(冒泡)
mouseout鼠标离开(冒泡)
mousedown鼠标按下
mouseup鼠标释放

键盘事件

事件触发时机
keydown按键按下
keyup按键释放
keypress按键按下(已废弃)
text
document.addEventListener('keydown', (e) => {
    console.log(e.key);      // 'Enter', 'a'
    console.log(e.code);     // 'Enter', 'KeyA'
    console.log(e.keyCode);  // 13(已废弃)
});

表单事件

事件触发时机
submit表单提交
change值改变后失焦触发
input值改变时触发
focus获得焦点
blur失去焦点

要点总结

  1. 事件流:捕获→目标→冒泡三阶段
  2. addEventListener:推荐使用,支持多个处理函数
  3. 事件委托:利用冒泡在父元素统一处理
  4. preventDefault:阻止默认行为
  5. stopPropagation:阻止事件传播

📝 发现内容有误?点击此处直接编辑

← 上一篇 DOM遍历与选择器
下一篇 → 定时器与动画帧
想查看更多题目和详细解析?
小程序提供完整的题库、模拟考试和详细解析
马上就来

长按或扫描二维码,立即体验

扫码体验小程序
马上就来
使用微信扫描二维码
立即体验完整题库