HTML DOM事件详解
编程小白入门必备 – 大白话解释所有概念,附实例演示
知识导航
什么是DOM事件?
DOM事件就是发生在HTML元素上的”事情”。比如用户点击按钮、移动鼠标、按下键盘按键等等。
你可以把DOM事件想象成网页元素的”感觉系统”:
- 按钮能”感觉”到被点击了
- 输入框能”感觉”到用户在输入内容
- 图片能”感觉”到鼠标悬停在它上面
💡 重要概念:当事件发生时,我们可以让网页执行一些JavaScript代码作为响应,这就像给网页元素添加了”反应能力”。
事件处理的基本原理:
- 用户与网页交互(如点击按钮)
- 浏览器检测到发生的事件
- 浏览器找到对应的JavaScript事件处理函数
- 执行事件处理函数中的代码
常见事件类型
下面是一些最常用的DOM事件类型:
事件类型 | 触发时机 | 应用场景 |
---|---|---|
click | 鼠标点击元素时 | 按钮点击、链接点击 |
dblclick | 鼠标双击元素时 | 编辑内容、打开详细视图 |
mouseover | 鼠标移入元素上方时 | 显示提示信息、改变样式 |
mouseout | 鼠标移出元素时 | 隐藏提示信息、恢复样式 |
mousemove | 鼠标在元素上移动时 | 拖拽操作、跟随鼠标效果 |
keydown | 键盘按键被按下时 | 表单输入实时校验、快捷键 |
keyup | 键盘按键被松开时 | 输入验证、搜索建议 |
change | 表单元素内容改变时 | 表单验证、动态更新内容 |
focus | 元素获得焦点时 | 输入框高亮、显示帮助信息 |
blur | 元素失去焦点时 | 表单验证、保存草稿 |
load | 资源完成加载时 | 页面初始化操作 |
📌 提示:实际有上百种DOM事件,但掌握上面这些常用事件就能应对大多数开发需求。
绑定事件的三种方式
让网页元素响应事件,需要把事件和处理函数”绑定”在一起。主要有三种方式:
1. HTML内联方式(不推荐)
直接在HTML元素上添加事件属性:
优点:简单直接
缺点:HTML和JavaScript代码混在一起,难以维护
2. DOM属性方式
通过JavaScript直接给DOM元素的事件属性赋值:
button.onclick = function() {
alert(“按钮被点击了!”);
};
优点:简单清晰
缺点:一个元素只能绑定一个同类事件
3. addEventListener方式(推荐)
使用addEventListener方法绑定事件:
button.addEventListener(“click”, function() {
console.log(“第一个处理函数执行了”);
});
button.addEventListener(“click”, function() {
console.log(“第二个处理函数也执行了”);
});
优点:可以绑定多个事件处理函数,能控制事件传播阶段
缺点:语法稍复杂
事件日志:
事件对象
当事件发生时,浏览器会创建一个事件对象,它包含事件相关的所有信息。
在事件处理函数中,我们可以通过参数获取这个对象:
// 这里的event就是事件对象
console.log(event);
});
事件对象的重要属性和方法:
event.target
– 实际触发事件的元素event.currentTarget
– 绑定事件处理函数的元素event.type
– 事件类型(如”click”)event.preventDefault()
– 阻止事件的默认行为event.stopPropagation()
– 阻止事件传播
💡 理解事件对象:就像你被蚊子叮了,你的大脑会收到一个”事件对象”,包含被叮位置、疼痛程度等信息。
事件流:冒泡与捕获
当事件发生在嵌套元素上时,事件传播分为三个阶段:
1. 捕获阶段(从上往下)
事件从最外层祖先元素向下传播到事件目标
2. 目标阶段
事件到达实际触发事件的元素
3. 冒泡阶段(从下往上)
事件从事件目标向上传播到最外层祖先元素
📣 比喻:像一块石头扔进水里,先下沉(捕获),然后产生波纹(目标),最后波纹扩散到水面各处(冒泡)
示例:点击嵌套元素
<div id=”parent”>
<div id=”child”>点击我</div>
</div>
</div>
点击child元素时的事件传播顺序:
- 捕获阶段:grandparent → parent
- 目标阶段:child
- 冒泡阶段:child → parent → grandparent
事件日志:
事件委托
事件委托是一种利用事件冒泡机制的技术。当多个子元素需要相同的事件处理时,我们在父元素上绑定事件,然后通过事件对象判断具体是哪个子元素被触发。
为什么使用事件委托?
- 减少事件处理程序数量,提高性能
- 动态添加的子元素自动获得事件处理
- 代码更简洁,更易维护
示例:点击列表中任意项
<li>项目 1</li>
<li>项目 2</li>
<li>项目 3</li>
</ul>
// 传统方式(为每个li绑定事件)
const items = document.querySelectorAll(‘#myList li’);
items.forEach(item => {
item.addEventListener(‘click’, handleClick);
});
// 事件委托方式(只需在ul上绑定一次)
const list = document.getElementById(‘myList’);
list.addEventListener(‘click’, function(event) {
if (event.target.tagName === ‘LI’) {
// 处理点击事件
console.log(‘你点击了:’, event.target.textContent);
}
});
点击下面任意水果:
- 🍎 苹果
- 🍌 香蕉
- 🍊 橙子
- 🍇 葡萄
- 🍓 草莓
你选择了:
阻止事件默认行为
许多事件有默认行为,比如:
- 点击链接会跳转到新页面
- 点击表单提交按钮会提交表单
- 点击复选框会切换选中状态
有时我们需要阻止这些默认行为,使用:
event.preventDefault(); // 阻止默认行为
// 其他处理代码
});
阻止事件传播
使用event.stopPropagation()
可以阻止事件继续传播(冒泡或捕获)
⚠ 注意:除非有特殊需要,否则不要随意阻止事件传播,这可能导致其他事件处理程序无法正常工作
实际应用示例
表单验证
form.addEventListener(‘submit’, function(event) {
const email = document.getElementById(’email’).value;
const password = document.getElementById(‘password’).value;
if (!email.includes(‘@’)) {
alert(‘请输入有效的邮箱地址’);
event.preventDefault(); // 阻止表单提交
}
if (password.length < 6) {
alert(‘密码长度至少6位’);
event.preventDefault();
}
});
图片灯箱效果
const thumbnails = document.querySelectorAll(‘.thumbnail’);
const lightbox = document.getElementById(‘lightbox’);
const lightboxImg = document.getElementById(‘lightbox-img’);
thumbnails.forEach(thumb => {
thumb.addEventListener(‘click’, function() {
lightboxImg.src = this.dataset.fullsize;
lightbox.style.display = ‘block’;
});
});
// 点击灯箱背景关闭
lightbox.addEventListener(‘click’, function(event) {
if (event.target === lightbox) {
lightbox.style.display = ‘none’;
}
});