事件处理(Event)
jQuery 提供了统一的事件绑定机制,解决了浏览器差异和事件绑定的复杂性。
基础事件绑定
click / dblclick
// 绑定点击事件
$('#btn').click(function() {
alert('点击了!')
})
// 双击
$('#item').dblclick(function() {
console.log('双击了')
})
键盘事件
// keydown(按下)
$('#input').keydown(function(e) {
console.log('按下的键:', e.key, '键码:', e.keyCode)
if (e.keyCode === 13) { // 回车键
console.log('回车键')
}
})
// keyup(释放)
$('#input').keyup(function(e) {
// 常用于实时搜索
var keyword = $(this).val()
if (keyword) {
search(keyword)
}
})
// keypress(输入字符)
$('#input').keypress(function(e) {
console.log(String.fromCharCode(e.charCode)) // 获取输入的字符
})
鼠标事件
$('#box')
.mouseenter(function() {
$(this).addClass('hover')
})
.mouseleave(function() {
$(this).removeClass('hover')
})
.mousedown(function() {
console.log('按下')
})
.mouseup(function() {
console.log('释放')
})
表单事件
// 提交表单
$('form').submit(function(e) {
e.preventDefault() // 阻止默认提交
var data = $(this).serialize() // 序列化表单
console.log(data)
})
// 输入框变化
$('#input').change(function() {
console.log('值改变了')
})
// 实时输入(每敲一个键都触发)
$('#input').input(function() {
console.log('当前值:', $(this).val())
})
// 获得/失去焦点
$('#input').focus(function() {
$(this).addClass('focused')
})
$('#input').blur(function() {
$(this).removeClass('focused')
})
事件委托(Event Delegation)
为什么要用事件委托?
// ❌ 问题:动态添加的元素不会绑定事件
$('li').click(function() { /* 不会对新增的 li 生效 */ })
$('#add-btn').click(function() {
$('#list').append('<li>新项目</li>') // 新 li 没有 click 事件
})
// ✅ 解决:使用事件委托
$('#list').on('click', 'li', function() {
// 这里的函数对 #list 内所有 li(包括后来添加的)都生效
console.log('点击了:', $(this).text())
})
原理:事件冒泡,把事件绑定在父元素上,利用 event.target 判断子元素。
优势:
- 动态元素也能响应
- 减少事件绑定数量(性能优化)
阻止默认行为和冒泡
$('a').click(function(e) {
e.preventDefault() // 阻止默认行为(如链接跳转)
e.stopPropagation() // 阻止事件冒泡(不会传给父元素)
e.stopImmediatePropagation() // 阻止其他同类型事件也执行
console.log('链接点击被拦截')
})
事件对象(Event Object)
$('#input').keydown(function(e) {
// e 是事件对象
console.log(e.type) // 事件类型: "keydown"
console.log(e.target) // 触发事件的元素
console.log(e.currentTarget) // 当前绑定事件的元素
console.log(e.key) // 按键名称(现代浏览器)
console.log(e.keyCode) // 键码(传统)
console.log(e.which) // jQuery 封装的通用键码
console.log(e.pageX, e.pageY) // 鼠标坐标(鼠标事件)
})
一次性事件
// 只触发一次
$('#btn').one('click', function() {
alert('只显示一次')
// 之后再点不会触发
})
常用示例
1. 表单验证
$('#username').blur(function() {
var val = $(this).val()
if (val.length < 3) {
$(this).next('.error').text('用户名至少3个字符').show()
} else {
$(this).next('.error').hide()
}
})
$('#form').submit(function(e) {
e.preventDefault()
if (validate()) {
this.submit()
}
})
2. 键盘快捷键
$(document).keydown(function(e) {
// Ctrl + S 保存
if (e.ctrlKey && e.key === 's') {
e.preventDefault()
save()
}
// ESC 关闭弹窗
if (e.key === 'Escape') {
closeModal()
}
})
3. 拖拽实现(基础)
var $drag = $('#drag-box')
var isDragging = false
var offsetX, offsetY
$drag.mousedown(function(e) {
isDragging = true
offsetX = e.pageX - $drag.offset().left
offsetY = e.pageY - $drag.offset().top
$('body').css('cursor', 'grabbing')
})
$(document).mousemove(function(e) {
if (isDragging) {
$drag.css({
left: e.pageX - offsetX,
top: e.pageY - offsetY
})
}
}).mouseup(function() {
isDragging = false
$('body').css('cursor', 'default')
})
示例:Todo List 的事件绑定
$('#todo-form').submit(function(e) {
e.preventDefault()
addTodo($('#todo-input').val())
})
// 使用事件委托处理动态添加的任务
$('#todo-list').on('click', '.todo-item', function() {
$(this).toggleClass('completed')
})
$('#todo-list').on('click', '.delete-btn', function(e) {
e.stopPropagation() // 阻止冒泡,不触发 toggle
$(this).closest('.todo-item').remove()
})
下一节
事件处理完后,就可以让页面动起来了——接下来学习 动画效果。