理解 JavaScript 事件的基本概念与触发机制
掌握常见事件类型(鼠标、键盘、表单、窗口等)
熟练使用三种事件绑定方式,优先采用 addEventListener
深入理解事件冒泡、捕获与事件委托
能够阻止默认行为(preventDefault)和停止传播(stopPropagation)
在实际项目中实现表单验证、动态内容、交互列表等典型应用
事件(Event)是浏览器中发生的动作或状态变化,可以由用户操作(如点击、输入)或浏览器自身(如页面加载完成)触发。
<button onclick="myFun()">点击我</button>
<p id="main"></p>
<script>
function myFun() {
document.getElementById("main").innerHTML = "Hello, Coder!";
}
</script>用户点击按钮 → 触发 click 事件
执行 myFun() → 动态更新页面内容
事件让网页从“静态展示”变为“动态交互”。
// 鼠标移动追踪
document.addEventListener("mousemove", (e) => {
console.log(`鼠标位置: (${e.clientX}, ${e.clientY})`);
});
// 键盘按下监听
document.addEventListener("keydown", (e) => {
console.log(`按下了键: ${e.key}`);
});不推荐
<button onclick="alert('已点击!')">点击</button>❌ 缺点:HTML 与 JS 耦合,难以维护,无法复用。
const btn = document.getElementById("myBtn");
btn.onclick = () => {
alert("按钮被点击了!");
};⚠️ 限制:只能绑定一个处理函数,后续赋值会覆盖前一个。
addEventListener()推荐方式
btn.addEventListener("click", () => {
alert("使用 addEventListener 触发!");
});优势:
可绑定多个监听器
支持移除监听器(removeEventListener)
可控制捕获 / 冒泡阶段
更符合现代 Web 标准
事件在 DOM 树中传播分为两个阶段:

从根节点(window)向下传递到目标元素
addEventListener 第三个参数设为 true 启用
从目标元素向上传播回根节点
// 捕获阶段监听
div.addEventListener("click", () => {
console.log("Div(捕获阶段)");
}, true);
// 冒泡阶段监听(默认)
button.addEventListener("click", (e) => {
console.log("Button(冒泡阶段)");
e.stopPropagation(); // 阻止继续冒泡
});默认情况下,所有事件监听器都在冒泡阶段执行。
Event Delegation
原理:利用事件冒泡,将监听器绑定到父元素,统一处理子元素事件。
优势
减少内存占用(只需一个监听器)
动态添加的子元素自动生效
示例:交互式列表
<ul id="list">
<li>项目 1</li>
<li>项目 2</li>
<li>项目 3</li>
</ul>
<script>
document.getElementById("list").addEventListener("click", (e) => {
if (e.target.tagName === "LI") {
e.target.style.backgroundColor = "yellow";
console.log("点击了:", e.target.textContent);
}
});
</script>即使后续通过 JS 添加新的
<li>,点击依然有效!
某些元素有内置行为(如 <a> 跳转、<form> 提交),可用 preventDefault() 取消。
// 阻止链接跳转
document.querySelector("a").addEventListener("click", (e) => {
e.preventDefault();
console.log("链接跳转已被阻止");
});
// 表单验证示例
document.querySelector("#myForm").addEventListener("submit", (e) => {
const input = document.querySelector("#username");
if (!input.value.trim()) {
e.preventDefault(); // 阻止提交
alert("用户名不能为空!");
}
});
preventDefault()不影响事件传播,如需同时停止传播,需额外调用stopPropagation()。
<form id="userForm">
<input type="text" id="username" placeholder="请输入用户名" />
<button type="submit">提交</button>
</form>
<script>
document.getElementById("userForm").addEventListener("submit", (e) => {
const value = document.getElementById("username").value;
if (!value) {
e.preventDefault();
alert("请输入内容!");
}
});
</script>document.getElementById("addBtn").addEventListener("click", () => {
const newDiv = document.createElement("div");
newDiv.textContent = "新元素已添加";
newDiv.style.margin = "10px 0";
newDiv.style.padding = "8px";
newDiv.style.backgroundColor = "#f0f0f0";
document.body.appendChild(newDiv);
});高亮点击项
document.getElementById("interactiveList").addEventListener("click", (e) => {
if (e.target.matches("li")) {
// 移除其他项的高亮
document.querySelectorAll("#interactiveList li").forEach(li => {
li.style.backgroundColor = "";
});
// 高亮当前项
e.target.style.backgroundColor = "#ffeb3b";
}
});以下代码点击按钮后会输出什么?为什么?
<div onclick="console.log('Div')">
<button onclick="console.log('Button')">Click</button>
</div>如何实现一个“点击页面任意位置关闭弹窗”的功能?需要注意什么问题?(提示:考虑事件委托与阻止冒泡)