在 Web 前端开发中,实现网页交互性是提升用户体验的核心。通过 JavaScript 的 Web APIs,我们可以为 DOM 元素注册事件,实现各种响应式的网页特效。本文将详细介绍事件监听的核心概念、实现方法及相关技术点。
一、事件与事件监听
什么是事件?
事件是编程语言中描述程序行为或状态变化的术语。当特定行为或状态发生时,会触发相应的处理函数。在网页中,常见的事件包括:
- 用户点击按钮(click)
- 鼠标经过元素(mouseover)
- 键盘按键(keydown)
- 表单输入(input)等
什么是事件监听?
事件监听是指为 DOM 元素添加事件监测机制,当指定事件发生(触发)时,自动执行预设的处理函数。在 JavaScript 中,我们使用 addEventListener 方法实现事件监听,其语法结构如下:
javascript
DOM元素.addEventListener('事件类型', 事件处理函数);
二、事件三要素
实现事件监听需要明确三个核心要素:
- 事件源:被触发事件的 DOM 元素(需要先获取该元素)
- 事件类型:触发事件的方式(如点击、鼠标经过等,需用引号包裹)
- 事件处理函数:事件触发后执行的逻辑(每次触发都会执行)
实例演示:点击按钮改变文字颜色
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>事件监听示例</title>
</head>
<body>
<h3>事件监听演示</h3>
<p id="text">这是一段可变色的文字</p>
<button id="btn">点击改变颜色</button>
<script>
// 1. 获取事件源(按钮元素)
const btn = document.querySelector('#btn');
// 2. 添加事件监听(事件类型为click,处理函数为匿名函数)
btn.addEventListener('click', function() {
// 3. 事件处理逻辑:改变文字颜色
const text = document.querySelector('#text');
text.style.color = 'red';
});
</script>
</body>
</html>
三、事件类型分类
根据交互方式的不同,事件可分为以下几类:
1. 鼠标事件
click:鼠标单击dblclick:鼠标双击mouseenter:鼠标移入元素mouseleave:鼠标离开元素
示例:鼠标移入移出效果
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
div {
width: 200px;
height: 200px;
background-color: pink;
}
</style>
</head>
<body>
<div></div>
<input type="text">
<script>
const div = document.querySelector('div')
// 1.鼠标触发
//鼠标经过
div.addEventListener('mouseenter', function () {
div.style.backgroundColor = 'skyblue'
})
// 鼠标离开
div.addEventListener('mouseleave', function () {
div.style.backgroundColor = 'red'
})
</script>
</body>
</html>
2. 键盘事件
keydown:键盘按下时触发keyup:键盘抬起时触发
示例:监听回车键
html
<input type="text" placeholder="按回车提交">
<script>
const input = document.querySelector('input');
input.addEventListener('keyup', function(e) {
if (e.key === 'Enter') {
console.log('提交内容:', this.value);
}
});
</script>
3. 表单与焦点事件
focus:元素获得焦点(如输入框被点击)blur:元素失去焦点(如输入框被点击后又点击其他地方)input:表单元素内容发生变化时触发
四、事件对象
当事件被触发时,浏览器会自动创建一个事件对象 ,包含与该事件相关的详细信息。事件处理函数的第一个参数即为事件对象,通常命名为 e、event 或 ev。
常用事件对象属性
type:事件类型(如 'click'、'keyup')clientX/clientY:光标相对于浏览器窗口的坐标offsetX/offsetY:光标相对于当前元素的坐标key:键盘事件中按下的键值
示例:获取鼠标位置
html
<button>点击我</button>
<script>
const btn = document.querySelector('button');
btn.addEventListener('click', function(e) {
console.log('事件类型:', e.type);
console.log('相对于窗口位置:', e.clientX, e.clientY);
console.log('相对于按钮位置:', e.offsetX, e.offsetY);
});
</script>
五、环境对象 this
在函数内部,this 是一个特殊的环境变量,代表当前函数运行时所处的环境。其值取决于函数的调用方式:
- 普通函数调用时,
this指向window - 事件处理函数中,
this指向触发事件的 DOM 元素(事件源)
示例:使用 this 简化代码
html
<button>点击变色</button>
<script>
const btn = document.querySelector('button');
btn.addEventListener('click', function() {
// this 指向当前点击的按钮元素
this.style.color = 'red';
this.style.backgroundColor = 'black';
});
</script>
六、事件监听的不同方式
1. 传统方式(L0 事件)
通过 on 前缀绑定事件,特点是同一事件只能绑定一个处理函数(后面的会覆盖前面的)。
javascript
const btn = document.querySelector('button');
btn.onclick = function() {
console.log('第一次点击'); // 不会执行
};
btn.onclick = function() {
console.log('第二次点击'); // 只会执行这个
};
2. 推荐方式(L2 事件)
使用 addEventListener 方法,支持同一事件绑定多个处理函数,按绑定顺序执行。
javascript
const btn = document.querySelector('button');
btn.addEventListener('click', function() {
console.log('第一次点击');
});
btn.addEventListener('click', function() {
console.log('第二次点击');
});
// 点击后会依次输出两次日志
七、回调函数
当一个函数作为参数传递给另一个函数时,这个函数就称为回调函数。在事件监听中,事件处理函数本质上就是回调函数。
常见回调函数场景:
javascript
// 1. 事件监听中的回调函数
btn.addEventListener('click', function() {
console.log('我是事件回调函数');
});
// 2. 定时器中的回调函数
setInterval(function() {
console.log('我是定时器回调函数');
}, 1000);
八、巩固练习
以下 3 道练习题从基础到综合,分别对应事件绑定、事件对象应用、综合交互场景,帮助你巩固事件监听核心知识点。
练习 1:基础题 - 按钮控制元素显隐
需求
- 页面中有 1 个 "显示 / 隐藏" 按钮和 1 个默认隐藏的红色方块(宽高 200px)。
- 点击按钮时,切换方块的显示状态(显示→隐藏,隐藏→显示),同时按钮文字也同步切换("显示"→"隐藏","隐藏"→"显示")。
答案代码
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>按钮控制显隐</title>
<style>
.box {
width: 200px;
height: 200px;
background-color: red;
/* 默认隐藏 */
display: none;
margin-top: 10px;
}
</style>
</head>
<body>
<button id="toggleBtn">显示</button>
<div class="box"></div>
<script>
// 1. 获取事件源:按钮和方块
const toggleBtn = document.querySelector('#toggleBtn');
const box = document.querySelector('.box');
// 2. 绑定点击事件
toggleBtn.addEventListener('click', function() {
// 3. 切换方块显示状态
if (box.style.display === 'block' || box.style.display === '') {
box.style.display = 'none';
this.textContent = '显示'; // this指向按钮
} else {
box.style.display = 'block';
this.textContent = '隐藏';
}
});
</script>
</body>
</html>
练习 2:进阶题 - 键盘控制 div 移动
需求
- 页面中有 1 个黑色方块(宽高 100px,初始位置在页面左上角)。
- 按下键盘的 "上、下、左、右" 箭头键时,方块向对应方向移动(每次移动 10px)。
- 需通过事件对象的
key属性判断按下的是哪个方向键。
答案代码
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>键盘控制移动</title>
<style>
.box {
width: 100px;
height: 100px;
background-color: black;
/* 绝对定位实现移动 */
position: absolute;
top: 0;
left: 0;
}
</style>
</head>
<body>
<div class="box"></div>
<script>
// 1. 获取方块元素
const box = document.querySelector('.box');
// 初始化位置(单位:px)
let topPos = 0;
let leftPos = 0;
// 2. 给document绑定键盘抬起事件(全局监听键盘)
document.addEventListener('keyup', function(e) {
// 3. 通过事件对象e.key判断方向键
switch(e.key) {
case 'ArrowUp':
topPos -= 10;
break;
case 'ArrowDown':
topPos += 10;
break;
case 'ArrowLeft':
leftPos -= 10;
break;
case 'ArrowRight':
leftPos += 10;
break;
}
// 4. 更新方块位置
box.style.top = topPos + 'px';
box.style.left = leftPos + 'px';
});
</script>
</body>
</html>
练习 3:综合题 - 表单实时验证
需求
- 页面中有 1 个输入框(要求输入 6-12 位密码,包含数字和字母)和 1 个提示文本(默认隐藏)。
- 输入框输入内容时(
input事件),实时验证内容:- 长度小于 6 位:提示 "密码长度不能少于 6 位",颜色为红色。
- 长度大于 12 位:提示 "密码长度不能超过 12 位",颜色为红色。
- 长度符合要求但不含数字 / 字母:提示 "密码需包含数字和字母",颜色为红色。
- 全部符合要求:提示 "密码格式正确",颜色为绿色。
- 输入框失去焦点(
blur事件)时,若内容为空,提示 "密码不能为空",颜色为红色。
答案代码
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>表单实时验证</title>
<style>
.tip {
margin-top: 5px;
font-size: 14px;
display: none; /* 默认隐藏提示 */
}
</style>
</head>
<body>
<label>密码:</label>
<input type="text" id="password" placeholder="请输入6-12位密码(含数字和字母)">
<div class="tip" id="tip"></div>
<script>
// 1. 获取元素:输入框和提示文本
const password = document.querySelector('#password');
const tip = document.querySelector('#tip');
// 2. 实时输入验证(input事件)
password.addEventListener('input', function() {
const val = this.value; // 输入框内容
const hasNum = /\d/.test(val); // 判断是否含数字
const hasLetter = /[a-zA-Z]/.test(val); // 判断是否含字母
// 显示提示
tip.style.display = 'block';
// 验证逻辑
if (val.length < 6) {
tip.textContent = '密码长度不能少于6位';
tip.style.color = 'red';
} else if (val.length > 12) {
tip.textContent = '密码长度不能超过12位';
tip.style.color = 'red';
} else if (!hasNum || !hasLetter) {
tip.textContent = '密码需包含数字和字母';
tip.style.color = 'red';
} else {
tip.textContent = '密码格式正确';
tip.style.color = 'green';
}
});
// 3. 失去焦点验证(blur事件)
password.addEventListener('blur', function() {
if (this.value === '') {
tip.style.display = 'block';
tip.textContent = '密码不能为空';
tip.style.color = 'red';
}
});
</script>
</body>
</html>
总结
通过本文学习,我们掌握了:
- 事件三要素:事件源、事件类型、事件处理函数
- 常用事件类型:鼠标事件、键盘事件、表单事件等
- 事件对象的使用:获取事件相关信息
- 环境对象 this 的指向规则
- 事件监听的两种方式及区别