事件处理
事件处理是 JavaScript 中实现用户交互的核心机制。通过事件处理,网页可以响应用户的操作,如点击、键盘输入、鼠标移动等。
什么是事件?
事件是用户或浏览器执行的某种动作,如点击按钮、页面加载完成、提交表单等。JavaScript 可以监听这些事件并在事件发生时执行相应的代码。
常见事件类型
鼠标事件
javascript
// click - 鼠标点击
element.addEventListener("click", function() {
console.log("元素被点击了");
});
// dblclick - 鼠标双击
element.addEventListener("dblclick", function() {
console.log("元素被双击了");
});
// mouseover - 鼠标悬停
element.addEventListener("mouseover", function() {
console.log("鼠标悬停在元素上");
});
// mouseout - 鼠标离开
element.addEventListener("mouseout", function() {
console.log("鼠标离开了元素");
});
// mousedown - 鼠标按下
element.addEventListener("mousedown", function() {
console.log("鼠标在元素上按下");
});
// mouseup - 鼠标释放
element.addEventListener("mouseup", function() {
console.log("鼠标在元素上释放");
});键盘事件
javascript
// keydown - 键盘按下
inputElement.addEventListener("keydown", function(event) {
console.log("按键被按下:", event.key);
});
// keyup - 键盘释放
inputElement.addEventListener("keyup", function(event) {
console.log("按键被释放:", event.key);
});
// keypress - 字符键按下(已废弃,使用 input 事件代替)
inputElement.addEventListener("keypress", function(event) {
console.log("字符键被按下:", event.key);
});表单事件
javascript
// submit - 表单提交
formElement.addEventListener("submit", function(event) {
event.preventDefault(); // 阻止默认提交行为
console.log("表单被提交");
});
// change - 表单元素值改变
inputElement.addEventListener("change", function() {
console.log("输入值改变了");
});
// input - 输入时触发
inputElement.addEventListener("input", function() {
console.log("正在输入:", this.value);
});
// focus - 元素获得焦点
inputElement.addEventListener("focus", function() {
console.log("输入框获得焦点");
});
// blur - 元素失去焦点
inputElement.addEventListener("blur", function() {
console.log("输入框失去焦点");
});窗口事件
javascript
// load - 页面加载完成
window.addEventListener("load", function() {
console.log("页面完全加载");
});
// DOMContentLoaded - DOM 构建完成
document.addEventListener("DOMContentLoaded", function() {
console.log("DOM 构建完成");
});
// resize - 窗口大小改变
window.addEventListener("resize", function() {
console.log("窗口大小改变为:", window.innerWidth, "x", window.innerHeight);
});
// scroll - 页面滚动
window.addEventListener("scroll", function() {
console.log("页面滚动到:", window.scrollY);
});事件处理方式
HTML 内联事件处理器(不推荐)
html
<button onclick="alert('Hello')">点击我</button>DOM 属性事件处理器
javascript
let button = document.querySelector("button");
button.onclick = function() {
alert("Hello");
};
// 只能绑定一个处理函数
button.onclick = function() {
console.log("这会覆盖之前的处理函数");
};addEventListener 方法(推荐)
javascript
let button = document.querySelector("button");
// 添加事件监听器
button.addEventListener("click", function() {
alert("Hello");
});
// 可以添加多个事件监听器
button.addEventListener("click", function() {
console.log("按钮被点击了");
});
// 使用箭头函数
button.addEventListener("click", () => {
console.log("箭头函数处理点击事件");
});事件对象
事件处理函数会接收一个事件对象参数,包含有关事件的详细信息:
javascript
button.addEventListener("click", function(event) {
console.log("事件类型:", event.type);
console.log("目标元素:", event.target);
console.log("事件发生时间:", event.timeStamp);
// 鼠标事件特有属性
if (event.type === "click") {
console.log("鼠标位置:", event.clientX, event.clientY);
}
// 键盘事件特有属性
if (event.type === "keydown") {
console.log("按键码:", event.keyCode);
console.log("是否按下 Ctrl:", event.ctrlKey);
console.log("是否按下 Shift:", event.shiftKey);
console.log("是否按下 Alt:", event.altKey);
}
});事件传播
事件在 DOM 树中会经历三个阶段:
- 捕获阶段:事件从 document 向下传播到目标元素
- 目标阶段:事件到达目标元素
- 冒泡阶段:事件从目标元素向上传播到 document
html
<div id="parent">
<button id="child">点击我</button>
</div>javascript
let parent = document.getElementById("parent");
let child = document.getElementById("child");
// 捕获阶段监听器
parent.addEventListener("click", function() {
console.log("父元素捕获阶段");
}, true); // 第三个参数为 true 表示在捕获阶段触发
// 冒泡阶段监听器
parent.addEventListener("click", function() {
console.log("父元素冒泡阶段");
}, false); // 默认为 false,在冒泡阶段触发
child.addEventListener("click", function() {
console.log("子元素");
});
// 点击按钮时输出顺序:
// 父元素捕获阶段
// 子元素
// 父元素冒泡阶段阻止事件默认行为
某些事件有默认行为,可以使用 preventDefault() 方法阻止:
javascript
let link = document.querySelector("a");
link.addEventListener("click", function(event) {
event.preventDefault(); // 阻止链接跳转
console.log("链接被点击,但不会跳转");
});
let form = document.querySelector("form");
form.addEventListener("submit", function(event) {
event.preventDefault(); // 阻止表单提交
console.log("表单提交被阻止");
});阻止事件传播
可以使用 stopPropagation() 方法阻止事件继续传播:
javascript
let parent = document.getElementById("parent");
let child = document.getElementById("child");
child.addEventListener("click", function(event) {
event.stopPropagation(); // 阻止事件冒泡
console.log("子元素");
});
parent.addEventListener("click", function() {
console.log("父元素"); // 不会执行
});事件委托
利用事件冒泡机制,可以在父元素上处理子元素的事件:
html
<ul id="list">
<li>项目 1</li>
<li>项目 2</li>
<li>项目 3</li>
</ul>javascript
let list = document.getElementById("list");
// 使用事件委托处理所有 li 元素的点击事件
list.addEventListener("click", function(event) {
if (event.target.tagName === "LI") {
console.log("点击了:", event.target.textContent);
}
});
// 动态添加的 li 元素也会自动具有事件处理能力
let newLi = document.createElement("li");
newLi.textContent = "项目 4";
list.appendChild(newLi); // 新添加的元素自动具有点击事件处理移除事件监听器
javascript
function handleClick() {
console.log("按钮被点击了");
}
// 添加事件监听器
button.addEventListener("click", handleClick);
// 移除事件监听器
button.removeEventListener("click", handleClick);自定义事件
javascript
// 创建自定义事件
let customEvent = new CustomEvent("myEvent", {
detail: { message: "自定义事件数据" }
});
// 监听自定义事件
element.addEventListener("myEvent", function(event) {
console.log("自定义事件被触发:", event.detail.message);
});
// 触发自定义事件
element.dispatchEvent(customEvent);最佳实践
优先使用 addEventListener:避免使用内联事件处理器和 DOM 属性事件处理器。
正确处理 this 绑定:
javascript
class Button {
constructor(element) {
this.element = element;
this.clickCount = 0;
// 使用箭头函数保持 this 绑定
this.element.addEventListener("click", () => {
this.handleClick();
});
}
handleClick() {
this.clickCount++;
console.log(`点击次数: ${this.clickCount}`);
}
}- 及时移除事件监听器:避免内存泄漏。
javascript
function setup() {
function handler() {
console.log("处理事件");
}
button.addEventListener("click", handler);
// 在适当时候移除监听器
// button.removeEventListener("click", handler);
}使用事件委托:对于动态内容或大量相似元素,使用事件委托提高性能。
阻止不必要的默认行为:只在需要时才调用
preventDefault()。合理使用事件传播:理解事件传播机制,在适当时候使用捕获或冒泡阶段。
通过掌握事件处理机制,可以创建丰富交互的网页应用,提升用户体验。