📣读完这篇文章里你能收获到
- 理解事件驱动编程的基本概念和工作原理
- 掌握JavaScript中常见的事件类型及其应用场合
- 学习如何使用DOM API添加和移除事件监听器
- 探讨事件冒泡、事件捕获和事件委托等高级事件处理技术
文章目录
- 一、事件处理程序
- 1. HTML事件处理
- HTML事件处理的局限性
- 2. DOM0级事件处理
- DOM0级事件处理的特点
- 3. DOM2级事件处理
- DOM2级事件处理的特点
- 二、Event对象的属性和方法
- 1. 事件行为概念
- 1.1 事件默认行为
- 1.2 事件冒泡
- 2. Event对象属性
- 3. Event对象方法
- 三、事件类型
- 1. 鼠标事件
- 2. 键盘事件
- 3. 触摸事件
- 4. 窗口事件
- 5. 表单事件
- 四、高级事件处理技术
- 1. 事件冒泡和事件捕获
- 2. 事件委托
一、事件处理程序
1. HTML事件处理
HTML事件处理是通过在HTML元素上直接定义事件处理器来处理事件的一种方式。
<button onclick="handleClick()">Click me</button>
在上面的例子中,我们为按钮元素定义了一个onclick事件处理器,当用户点击按钮时,会调用handleClick函数。
HTML事件处理的局限性
- 不支持事件捕获阶段。
- 无法使用addEventListener()和removeEventListener()方法添加或移除事件处理器。
- 只能定义一个事件处理器,如果需要多个处理器,需要手动合并逻辑。
2. DOM0级事件处理
DOM0级事件处理是在JavaScript中直接为DOM元素的事件属性赋值来添加事件处理器的方式。
let button = document.getElementById("myButton");
button.onclick = function() {
console.log("Button clicked!");
};
在这个例子中,我们为按钮元素的onclick属性赋值为一个函数,当用户点击按钮时,该函数会被调用。
DOM0级事件处理的特点
- 支持多个事件处理器,后添加的处理器会覆盖之前的处理器。
- 不支持事件捕获阶段。
- 使用on前缀的属性(如onclick、onmouseover等)添加事件处理器。
3. DOM2级事件处理
DOM2级事件处理是通过addEventListener()
和removeEventListener()
方法来添加和移除事件处理器的标准方式。
let button = document.getElementById("myButton");
// 添加事件监听器
function handleClick(event) {
console.log("Button clicked!");
}
button.addEventListener("click", handleClick);
// 移除事件监听器
button.removeEventListener("click", handleClick);
DOM2级事件处理的特点
- 支持事件捕获和冒泡阶段。
- 支持多个事件处理器,可以同时添加多个处理器。
- 提供更灵活的事件处理机制。
二、Event对象的属性和方法
属性/方法 | 描述 |
---|---|
type | 事件的类型,如 “click”、“mouseover” 等。 |
target | 触发事件的元素。 |
currentTarget | 绑定事件处理器的元素。 |
preventDefault() | 阻止事件的默认行为。 |
stopPropagation() | 阻止事件继续向上级元素传播(事件冒泡)。 |
1. 事件行为概念
1.1 事件默认行为
事件的默认行为是指当特定事件发生时,浏览器根据该事件类型自动执行的预定义操作。这些操作通常是与用户交互相关的常见动作,如点击链接跳转、提交表单、右键菜单弹出等。
例如,当用户点击一个HTML链接(标签)时,浏览器的默认行为是导航到href属性指定的URL。另一个例子是,当用户提交一个HTML表单时,浏览器的默认行为是发送表单数据到action属性指定的URL。
1.2 事件冒泡
事件冒泡是一种事件传播机制,当一个元素上的事件被触发时,该事件不仅会在该元素上执行相应的事件处理器,还会从该元素开始,沿着DOM树向上逐级传播到父元素、祖元素,直到到达根元素(通常为document对象)。在这个过程中,每个包含事件处理器的父元素都会依次执行其对应的处理器。
事件冒泡使得我们可以更容易地处理与整个父元素或容器相关的事件,而不仅仅局限于触发事件的具体子元素。通过在父元素上添加事件处理器,可以简化代码并避免为每个子元素单独添加处理器。1.2
2. Event对象属性
- type:表示事件的类型,如 “click”、“mouseover” 等。
案例代码:
let button = document.getElementById("myButton");
button.addEventListener("click", function(event) {
console.log("Event type:", event.type);
});
- target 和 currentTarget
- target属性表示触发事件的元素。
- currentTarget属性表示绑定事件处理器的元素。
案例代码:
let container = document.getElementById("container");
let button = document.createElement("button");
button.textContent = "Click me";
container.appendChild(button);
container.addEventListener("click", function(event) {
console.log("Target:", event.target); // 输出触发事件的元素(按钮)
console.log("CurrentTarget:", event.currentTarget); // 输出绑定事件处理器的元素(容器)
});
button.addEventListener("click", function(event) {
console.log("Target (inner):", event.target); // 输出触发事件的元素(按钮)
console.log("CurrentTarget (inner):", event.currentTarget); // 输出绑定事件处理器的元素(按钮)
});
3. Event对象方法
- preventDefault():用于阻止事件的默认行为。
- 案例:
当用户点击一个HTML链接(标签)时,浏览器的默认行为是导航到href属性指定的URL。另一个例子是,当用户提交一个HTML表单时,浏览器的默认行为是发送表单数据到action属性指定的URL。
在JavaScript中,可以通过调用事件对象的preventDefault()
方法来阻止事件的默认行为。这样,即使事件发生了,浏览器也不会执行其默认的操作。
let link = document.getElementById("myLink");
link.addEventListener("click", function(event) {
event.preventDefault(); // 阻止链接的默认跳转行为
console.log("Link clicked, but not navigated.");
});
- stopPropagation():方法用于阻止事件继续向上级元素传播(事件冒泡)。
- 案例:
当用户点击按钮时,首先会输出"Child clicked!",然后由于事件冒泡,事件会继续向上传播到父元素,导致"Parent clicked!"也被输出。如果在子元素的事件处理器中使用了event.stopPropagation()
方法,那么事件将不会向上冒泡到父元素。
<div id="parent">
<button id="child">Click me</button>
</div>
<script>
let parent = document.getElementById("parent");
let child = document.getElementById("child");
// 在父元素上添加点击事件处理器
parent.addEventListener("click", function(event) {
console.log("Parent clicked!");
});
// 在子元素(按钮)上添加点击事件处理器
child.addEventListener("click", function(event) {
console.log("Child clicked!");
// 阻止事件继续向上冒泡到父元素
// 如果不使用此行代码,事件将继续冒泡到父元素
//event.stopPropagation();
});
</script>
三、事件类型
1. 鼠标事件
鼠标事件与用户使用鼠标与网页交互的行为相关。
事件名称 | 描述 |
---|---|
click | 用户单击鼠标按钮 |
dblclick | 用户双击鼠标按钮 |
mousedown | 用户按下任意鼠标按钮 |
mouseup | 用户释放任意鼠标按钮 |
mousemove | 用户移动鼠标时 |
mouseover | 鼠标指针进入某个元素 |
mouseout | 鼠标指针离开某个元素 |
mouseenter | 鼠标指针进入某个元素(不包括其后代元素) |
mouseleave | 鼠标指针离开某个元素(不包括其后代元素) |
DOM0级事件处理案例代码:
let button = document.getElementById("myButton");
// Click event
button.onclick = function() {
console.log("Button clicked (DOM0)!");
};
// Mouseover event
button.onmouseover = function() {
console.log("Mouse over the button (DOM0)!");
};
DOM2级事件处理案例代码:
let button = document.getElementById("myButton");
// Click event
button.addEventListener("click", function() {
console.log("Button clicked (DOM2)!");
});
// Mouseover event
button.addEventListener("mouseover", function() {
console.log("Mouse over the button (DOM2)!");
});
2. 键盘事件
键盘事件与用户使用键盘与网页交互的行为相关。
事件名称 | 描述 |
---|---|
keydown | 用户按下键盘上的键 |
keyup | 用户释放键盘上的键 |
keypress | 用户按下字符键(不包括功能键和修饰键) |
DOM0级事件处理案例代码:
document.onkeydown = function(event) {
if (event.key === "Enter") {
console.log("Enter key pressed (DOM0)!");
}
};
document.onkeyup = function(event) {
if (event.key === "Shift") {
console.log("Shift key released (DOM0)!");
}
};
DOM2级事件处理案例代码:
document.addEventListener("keydown", function(event) {
if (event.key === "Enter") {
console.log("Enter key pressed (DOM2)!");
}
});
document.addEventListener("keyup", function(event) {
if (event.key === "Shift") {
console.log("Shift key released (DOM2)!");
}
});
3. 触摸事件
触摸事件用于支持触摸设备的交互。
事件名称 | 描述 |
---|---|
touchstart | 用户开始触摸屏幕 |
touchmove | 用户在屏幕上移动手指 |
touchend | 用户结束触摸屏幕 |
touchcancel | 触摸事件被取消(例如系统中断或浏览器切换到另一个应用程序) |
请注意,由于触摸事件不支持DOM0级事件处理,以下仅提供DOM2级事件处理案例代码:
let touchArea = document.getElementById("touchArea");
touchArea.addEventListener("touchstart", function(event) {
console.log("Touch started (DOM2)!");
});
touchArea.addEventListener("touchmove", function(event) {
console.log("Touch moved (DOM2)!");
});
touchArea.addEventListener("touchend", function(event) {
console.log("Touch ended (DOM2)!");
});
4. 窗口事件
窗口事件与浏览器窗口的状态或用户操作相关。
事件名称 | 描述 |
---|---|
load | 页面和所有资源完成加载 |
unload | 页面即将卸载 |
beforeunload | 页面即将卸载,可以返回一个字符串提示用户是否确认离开页面 |
resize | 浏览器窗口大小发生变化 |
scroll | 用户滚动了包含滚动条的元素 |
DOM0级事件处理案例代码:
window.onload = function() {
console.log("Page loaded (DOM0)!");
};
window.onresize = function() {
console.log("Window resized (DOM0)!");
};
window.onscroll = function() {
console.log("Window scrolled (DOM0)!");
};
DOM2级事件处理案例代码:
window.addEventListener("load", function() {
console.log("Page loaded (DOM2)!");
});
window.addEventListener("resize", function() {
console.log("Window resized (DOM2)!");
});
window.addEventListener("scroll", function() {
console.log("Window scrolled (DOM2)!");
});
5. 表单事件
表单事件与用户在表单元素上执行的操作相关。
事件名称 | 描述 |
---|---|
submit | 用户提交表单 |
input | 用户更改输入元素的内容 |
change | 用户更改输入元素的内容并失去焦点 |
focus | 元素获得焦点 |
blur | 元素失去焦点 |
DOM0级事件处理案例代码:
let inputElement = document.getElementById("myInput");
// Submit event (on the form element)
let formElement = document.getElementById("myForm");
formElement.onsubmit = function(event) {
event.preventDefault(); // Prevent default form submission
console.log("Form submitted (DOM0)!");
};
// Input event
inputElement.oninput = function() {
console.log("Input changed (DOM0)!");
};
// Change event
inputElement.onchange = function() {
console.log("Input changed and lost focus (DOM0)!");
};
// Focus event
inputElement.onfocus = function() {
console.log("Input gained focus (DOM0)!");
};
// Blur event
inputElement.onblur = function() {
console.log("Input lost focus (DOM0)!");
};
DOM2级事件处理案例代码:
let inputElement = document.getElementById("myInput");
// Submit event (on the form element)
let formElement = document.getElementById("myForm");
formElement.addEventListener("submit", function(event) {
event.preventDefault(); // Prevent default form submission
console.log("Form submitted (DOM2)!");
});
// Input event
inputElement.addEventListener("input", function() {
console.log("Input changed (DOM2)!");
});
// Change event
inputElement.addEventListener("change", function() {
console.log("Input changed and lost focus (DOM2)!");
});
// Focus event
inputElement.addEventListener("focus", function() {
console.log("Input gained focus (DOM2)!");
});
// Blur event
inputElement.addEventListener("blur", function() {
console.log("Input lost focus (DOM2)!");
});
四、高级事件处理技术
1. 事件冒泡和事件捕获
事件传播有三个阶段:事件捕获阶段、目标阶段和事件冒泡阶段。默认情况下,事件从最外层元素向内传播(事件冒泡),但在某些情况下,我们可能希望在事件捕获阶段处理事件。
// 使用事件捕获阶段
element.addEventListener("click", handleClick, { capture: true });
2. 事件委托
事件委托是一种优化事件处理的技术,通过将事件处理器添加到父元素上,来处理所有子元素的事件。这种方法可以减少事件处理器的数量,提高性能。
以下是一个事件委托的示例:
let container = document.getElementById("container");
// 添加事件监听器到父元素
container.addEventListener("click", handleContainerClick);
function handleContainerClick(event) {
let target = event.target;
if (target.tagName.toLowerCase() === "button") {
console.log("Button clicked:", target.id);
}
}