深入理解javascript事件处理机制
前言
在开发web应用程序时,事件处理机制是javascript中至关重要的一部分。许多高级特性,如事件冒泡、事件捕获和事件委托,都是通过事件处理来实现的。熟练掌握这些技术可以帮助我们更好地组织代码、提高代码效率并减少资源浪费
1️⃣事件捕获:
事件捕获是一种从根节点到目标节点的事件传递方式(默认)
2️⃣事件冒泡:
事件冒泡是一种从目标节点到根节点的事件传递方式
3️⃣事件流
JavaScript事件流是指当HTML页面中发生事件时,处理该事件的顺序和路径
通常情况下,事件流由三个阶段构成:捕获阶段,目标阶段和冒泡阶段
默认情况下,JavaScript事件执行顺序是:事件捕获—>目标阶段—>事件冒泡
4️⃣控制事件的处理
使用addEventListener()
函数
用来控制事件是在事件捕获阶段还是在事件冒泡阶段响应
- 当参数为
true
时,事件监听器将会在事件捕获阶段中执行 - 当 参数为
false
时,事件监听器将会在事件冒泡阶段中执行
参数:
target.addEventListener(type, listener [, options]);
- target:要添加事件的DOM节点。
- type:要添加的事件类型,如click、keydown等。
- listener:事件触发时要执行的函数(也称为回调函数)。可以是命名函数,也可以是匿名函数。
- options:可以是对象,也可以是布尔值,是对象时有三个常用属性:capture、once和passive
使用 addEventListener()
函数来添加事件监听器的好处在于可以指定事件的各种特性,从而更好地控制事件的行为
案例:
function handleClick(event) {
//执行完后不再冒泡
event.preventDefault();
event.stopPropagation();
console.log("按钮被点击了!");
}
const myButton = document.getElementById("myButton");
myButton.addEventListener("click", handleClick, {
capture: false, // true表示捕获,false表示冒泡
once: false, // 监听器是否只调用一次,调用后自动销毁
passive: false // 监听器是否阻止默认操作或停止事件冒泡
});
5️⃣阻止冒泡和默认行为
默认行为:
例如:a标签会自动跳转了,停止了默认行为后就不会自动跳转了,就需要自行设置属性
不阻止冒泡和默认行为:
- 事件堆积:大量事件执行
- 延迟:大量事件执行
- 不必要的操作:浏览器的自动操作,默认行为
案例:
const myButton = document.getElementById("myButton");
myButton.addEventListener('click', (event) => {
console.log("按钮被点击了!");
// 阻止事件冒泡
event.stopPropagation();
// 阻止默认行为
event.preventDefault();
//或者 return false,相当于同时执行阻止事件冒泡和默认行为,不过不建议使用
});
6️⃣避免事件泄漏
事件泄漏是指没有正确地添加或移除事件处理程序,导致页面上的事件处理函数被占用,从而引起内存泄漏的问题
方法:
- 正确添加和删除事件处理程序:使用
addEventlistener()
方法来添加事件监听器,用完就移除 - 使用事件委托:将事件处理函数添加到父元素,取而代之以通过父元素进行监听
- 使用闭包注意回收:避免变量无法回收
- 使用第三方库:如 React、Vue 等都针对事件管理提供了一些工具和 API
7️⃣事件委托
原理:
利用事件冒泡,将事件处理程序添加到父元素中,而不是在每个子元素上都添加处理程序
好处:
- 代码更清晰,容易维护和修改
- 提供代码性能,减少内容开销,降低页面加载事件
案例:
// 假如要给 ul#container 下所有 li 添加点击事件
const container = document.querySelector('ul#container');
// 在 ul 上监听 click 事件,对 li 判断触发事件类型,并且执行事件交互方法
container.addEventListener('click', (event) => {
if (event.target.tagName === 'LI') {
// 在这里执行点击交互逻辑,对当前被点中的 li 进行操作
}
});
结语
感谢读者阅读并关注博客文章,并对文章中提到的观点、建议或批评表示感谢