首页 / HTML5 入门教程 / 事件处理基础

HTML5 入门教程

事件处理基础

本教程共 110 篇 · 第 103 篇 · 更新于 2026-07-28 · 约 5 分钟阅读

HTML5HTML5 入门教程事件事件监听事件冒泡事件委托

103. 事件处理基础

本节目标:理解浏览器事件模型,掌握 addEventListener 的用法,了解事件冒泡、捕获和事件委托的原理。

什么是事件

事件是浏览器发出的通知:用户点击了、页面加载完成了、输入框内容变了……你的 JS 代码可以”监听”这些事件,然后做出响应。

三种监听方式

1. HTML 事件属性(不推荐)

<button onclick="alert('我被点了')">点我</button>

把 JS 写在 HTML 里,又乱又难维护。不要用这种方式

2. DOM 事件属性(有局限)

button.onclick = function () {
  alert("我被点了");
};

问题是只能绑一个。第二次赋值会覆盖第一次。

3. addEventListener(推荐)

button.addEventListener("click", function () {
  alert("我第一次被点");
});

button.addEventListener("click", function () {
  alert("我也能被点");
});

两个都会执行。这是标准做法。

addEventListener 详解

element.addEventListener(type, listener, options);
参数说明
type事件类型:clickkeydownsubmit
listener触发时执行的函数
options可选配置:captureoncepassive

once:只执行一次

button.addEventListener("click", function () {
  alert("我只执行一次");
}, { once: true });

事件对象

事件触发时,浏览器会把”事件对象”传给监听器:

element.addEventListener("click", function (event) {
  console.log(event.type);    // "click"
  console.log(event.target);  // 被点击的元素
  console.log(event.currentTarget); // 绑了监听器的元素
  console.log(event.clientX); // 鼠标 X 坐标
  console.log(event.clientY); // 鼠标 Y 坐标
});

常用属性:

属性说明
event.type事件类型
event.target触发事件的元素
event.currentTarget绑了监听的元素
event.preventDefault()阻止默认行为
event.stopPropagation()阻止事件冒泡
event.stopImmediatePropagation()阻止冒泡 + 阻止同元素其他监听器

事件冒泡和捕获

事件传播分三个阶段:

  1. 捕获阶段:从 window 一路向下到目标元素
  2. 目标阶段:到达实际被点击的元素
  3. 冒泡阶段:从目标元素一路向上回到 window
window → document → html → body → div → button(目标)→ div → body → ...
  捕获阶段                                   冒泡阶段

默认情况下,addEventListener 监听的是冒泡阶段。

// 第三个参数设为 true,监听捕获阶段
parent.addEventListener("click", handler, true);

事件委托:省事件监听器的利器

如果一个父元素下有大量子元素,每个子元素都绑监听器很浪费。

更好的做法:在父元素上绑一个监听器,利用冒泡原理判断是哪个子元素被点的

<ul id="list">
  <li data-id="1">项目一</li>
  <li data-id="2">项目二</li>
  <li data-id="3">项目三</li>
</ul>

<script>
  document.getElementById("list").addEventListener("click", function (e) {
    if (e.target.tagName === "LI") {
      console.log("点了:", e.target.dataset.id);
    }
  });
</script>

事件委托的好处:

  • 只需要一个监听器,性能更好
  • 新加子元素不需要重新绑定
  • 内存占用少
Tip

列表、表格、导航菜单这类重复性元素多的场景,用事件委托是最佳实践。

移除监听器

function handleClick() {
  console.log("clicked");
}

element.addEventListener("click", handleClick);

// 移除(必须用同一个函数引用)
element.removeEventListener("click", handleClick);

注意:匿名函数无法移除。所以想以后能移除的监听器,用命名函数。

常用事件速查

事件触发时机
click点击
dblclick双击
mousedown / mouseup鼠标按下 / 释放
mouseenter / mouseleave鼠标移入 / 移出(不冒泡)
mouseover / mouseout鼠标移入 / 移出(冒泡)
mousemove鼠标移动
keydown / keyup / keypress键盘事件
focus / blur获得 / 失去焦点
input输入内容变化
change值变化且失去焦点
submit表单提交
scroll滚动
load / DOMContentLoaded加载完成
Note

移动端用 touchstarttouchmovetouchend 等触摸事件。但现代浏览器也支持 Pointer Events(pointerdownpointermove),更统一。

阻止默认行为

有些元素有默认行为:链接跳转、表单提交、右键菜单……

// 阻止链接跳转
a.addEventListener("click", function (e) {
  e.preventDefault();
});

// 阻止表单提交
form.addEventListener("submit", function (e) {
  e.preventDefault();
  // 手动处理提交逻辑
});
Warning

preventDefault() 只阻止默认行为,不阻止事件传播。stopPropagation() 只阻止传播,不阻止默认行为。两者互不干扰。