🌈
个人主页: Hygge_Code
🔥
热门专栏:从0开始学习Java | Linux学习| 计算机网络
💫
个人格言: “既然选择了远方,便不顾风雨兼程”
JavaScript事件
事件基础:什么是事件与事件监听🤔
事件的概念
事件是编程时系统内发生的动作或事情,比如用户在页面上点击一个按钮、鼠标经过某个元素、按下键盘等。
事件监听
事件监听就是让程序检测是否有事件发生,一旦有事件触发,就立即调用一个函数做出响应。也称为"绑定事件"或"注册事件"。
事件监听有两个主要版本:
-
DOM L0 级事件
事件源.on事件 = function(){}这种方式的缺点是同一个事件只能绑定一个处理函数,新的会覆盖旧的。
-
DOM L2 级事件
事件源.addEventListener("事件", 事件处理函数)推荐使用这种方式,它可以为同一个事件绑定多个处理函数,且拥有更多事件特性。
| 特性 | DOM L0 事件 | DOM L2 事件 |
|---|---|---|
| 绑定语法 | 元素.on事件名 = 函数 | 元素.addEventListener(‘事件名’, 函数, 阶段) |
| 多事件绑定 | 不支持(后覆盖前) | 支持(多个函数按顺序执行) |
| 事件阶段 | 只支持冒泡 | 支持捕获/冒泡(第三个参数控制) |
| 移除方式 | 元素.on事件名 = null | 元素.removeEventListener(…) |
| 兼容性 | 所有浏览器(包括古老版本) | IE8及以下不支持(需用attachEvent) |
事件监听三要素
- 事件源:哪个DOM元素被事件触发了,需要先获取DOM元素
- 事件类型:用什么方式触发,比如鼠标点击、鼠标经过等
- 事件处理函数:事件触发后要执行的函数
// 示例:给按钮绑定点击事件
const btn = document.querySelector("button");
btn.addEventListener("click", function() {
confirm("按钮被点击");
});
常用事件类型🧾
鼠标事件
-
click:鼠标点击(左键单击) -
mouseenter:鼠标经过(进入元素时触发,不冒泡) -
mouseleave:鼠标离开(离开元素时触发,不冒泡)
const div1 = document.querySelector(".div1");
// 鼠标经过
div1.addEventListener("mouseenter", function() {
console.log("鼠标经过");
});
// 鼠标离开
div1.addEventListener("mouseleave", function() {
console.log("鼠标离开了哦");
});
焦点事件(主要用于表单元素)
-
focus:元素获得焦点(如输入框被点击或通过tab键选中) -
blur:元素失去焦点(如点击其他区域)
const input = document.querySelector("#input1");
input.addEventListener("focus", function() {
console.log("获得焦点");
});
input.addEventListener("blur", function() {
console.log("失去焦点");
});
键盘事件
-
keydown:键盘按键按下时触发(按住会持续触发) -
keyup:键盘按键抬起时触发
const input2 = document.querySelector("#input2");
input2.addEventListener("keydown", function() {
console.log("键盘按下");
});
input2.addEventListener("keyup", function() {
console.log("键盘弹起");
});
文本事件
-
input:用户输入时实时触发(包括键盘输入、粘贴、拖拽等方式改变内容)
const input1 = document.querySelector("#input1");
const div2 = document.querySelector(".div2");
input1.addEventListener("input", function() {
console.log(input1.value);
div2.innerText = `${input1.value.length}/200字`;
});
事件对象🍂
事件对象是一个包含事件触发相关信息的对象,在事件绑定的回调函数的第一个参数就是事件对象,通常命名为event、ev或e。
常用属性
-
type:获取当前事件的类型 -
clientX/clientY:获取光标相对于浏览器可见窗口左上角的位置 -
offsetX/offsetY:获取光标相对于当前DOM元素左上角的位置 -
key:用户按下键盘键的值(推荐使用,替代旧的keyCode) -
target:获取触发事件的元素
// 示例:键盘事件中判断按下的键
input2.addEventListener("keyup", function(e) {
console.log(e.key); // 输出按下的键
if (e.key === "Enter") {
console.log("我按下了回车键");
}
});
环境对象this🍂
在事件处理函数中,this代表当前函数运行时所处的环境,即触发事件的那个元素(事件源)。
const btn1 = document.querySelector("#btn2");
btn1.addEventListener("click", function() {
console.log(this); // 指向btn1元素
this.style.color = "red"; // 等价于btn1.style.color = "red"
});
事件流🐦🔥
事件流指的是事件完整执行过程中的流动路径,分为两个阶段:
1. 捕获阶段(从父到子)
从DOM的根元素开始去执行对应的事件(从外到里),需要通过addEventListener的第三个参数设置为true来启用。
// 事件捕获示例
document.addEventListener("click", function() {
confirm("我是爷爷document");
}, true);
father.addEventListener("click", function() {
confirm("我是爸爸");
}, true);
son.addEventListener("click", function() {
confirm("儿子");
}, true);
2. 冒泡阶段(从子到父)
当一个元素的事件被触发时,同样的事件将会在该元素的所有祖先元素中依次被触发,这是默认行为。
// 事件冒泡示例(默认行为)
document.addEventListener("click", function() {
confirm("我是爷爷document");
});
father.addEventListener("click", function() {
confirm("我是爸爸");
});
son.addEventListener("click", function() {
confirm("儿子");
});
阻止冒泡
有时我们需要阻止事件冒泡,避免影响父级元素,可使用事件对象的stopPropagation()方法。
son.addEventListener("click", function(e) {
confirm("儿子");
// 阻止事件冒泡
e.stopPropagation();
});
阻止默认行为
某些元素有默认行为(如链接跳转、表单提交),可以使用preventDefault()方法阻止。
const a = document.querySelector("a");
a.addEventListener("click", function(e) {
e.preventDefault(); // 阻止链接跳转
});
事件解绑🥝
1. L0级事件解绑
直接使用null覆盖即可:
btn.onclick = null;
2. L2级事件解绑
必须使用removeEventListener,且事件处理函数不能是匿名函数:
// 定义命名函数
function fn() {
alert("点击了");
}
// 绑定事件
btn.addEventListener("click", fn);
// 解绑事件
btn.removeEventListener("click", fn);
事件委托
事件委托利用事件冒泡的特点,将子元素的事件委托给父元素处理,无需为每个子元素单独绑定事件。
原理
当触发子元素事件时,事件会冒泡到父元素,通过判断事件源(e.target)来确定实际触发事件的子元素。
// 事件委托示例:点击ul中的li使文字变红
const ul = document.querySelector("ul");
ul.addEventListener("click", function(e) {
// 判断触发事件的是否是li元素
if (e.target.tagName === "LI") {
e.target.style.color = "red";
}
});
优点
- 减少事件绑定,提高性能
- 新增子元素时无需重新绑定事件
- 简化代码结构
如果我的内容对你有帮助,请 点赞 , 评论 , 收藏 。创作不易,大家的支持就是我坚持下去的动力!