jQuery事件机制
jQuery 事件机制详解
1. jQuery 事件发展历程(了解)
原生 JS 绑定事件
在原生 JavaScript 中,有两种常见的绑定事件的方式。
- 内联事件处理程序:通过 HTML 标签的事件属性(如
onclick
)直接绑定事件处理函数。不过这种方式会使 HTML 和 JavaScript 代码耦合度高,不推荐大量使用。示例代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>原生 JS 内联事件</title>
</head>
<body>
<button id="btn" onclick="alert('内联事件')">点击我</button>
</body>
</html>
- DOM0 级和 DOM2 级事件绑定:
- DOM0 级事件:通过直接给元素的事件属性赋值来绑定事件处理函数。但这种方式一个元素的同一事件类型只能绑定一个处理函数。示例代码如下:
document.getElementById("btn").onclick = function () {
alert("111");
};
document.getElementById("btn").onclick = function () {
alert("222"); // 这里会覆盖前面的事件处理函数
};
- **DOM2 级事件**:使用 `addEventListener` 方法绑定事件,它可以为元素的同一事件类型绑定多个处理函数。示例代码如下:
document.getElementById("btn").addEventListener("click", function () {
alert("333");
});
document.getElementById("btn").addEventListener("click", function () {
alert("444");
});
jQuery 事件绑定方式的演变
jQuery 对 JavaScript 事件进行了封装,提供了更优雅的事件处理语法和增强的处理能力。其事件绑定方式经历了从简单事件绑定到统一使用 on
方法的发展过程。
- 简单事件注册:
- 特点:可以直接使用 jQuery 提供的事件方法(如
click
、mouseenter
等)来绑定事件。但缺点是不能同时注册多个事件,并且不可动态注册事件(即对于后续动态添加到 DOM 中的元素,不会自动绑定该事件)。 - 示例代码:
- 特点:可以直接使用 jQuery 提供的事件方法(如
// 不可同时绑定,只能依次绑定
$(".box").click(function () {
console.log(111);
});
$(".box").mouseenter(function () {
console.log(222);
});
// 不可动态绑定,后添加的内容,不会有绑定事件
$("#btn").click(function () {
var $newDiv = $("<div>box1</div>");
$("body").append($newDiv);
});
- bind 方式注册事件:
- 特点:可以同时注册多个事件,通过在第一个参数中用空格分隔多个事件类型。但同样不支持动态注册事件。
- 示例代码:
// 2.2 bind 绑定 可同时绑定,不可动态绑定
$("div").bind("click mouseenter", function () {
console.log(333);
});
// 不可动态绑定
$("#btn").click(function () {
var $newDiv = $("<div>box1</div>");
$("body").append($newDiv);
});
- delegate 注册委托事件:
- 特点:支持同时注册多个事件,并且支持动态注册事件。它是一种事件委托机制,通过将事件绑定到一个父元素上,当子元素触发相应事件时,会冒泡到父元素上执行绑定的事件处理函数。但只能用于注册委托事件。
- 示例代码:
// 2.3 delegate 绑定 可同时,可动态,只能事件委托
$("#btn").click(function () {
var $newDiv = $("<div>box1</div>");
$("body").append($newDiv);
});
$("body").delegate('div', "click mouseenter", function () {
console.log(444);
});
- on 事件绑定:
- 特点:从 jQuery 1.7 版本以后,
on
方法统一了所有事件的处理方式,它既可以用于简单事件绑定,也可以用于事件委托,是推荐使用的事件绑定方法。
- 特点:从 jQuery 1.7 版本以后,
2. on 注册事件
on 注册简单事件
- 特点:可以同时注册多个事件,但不支持动态绑定(对于后续动态添加到 DOM 中的元素,不会自动绑定该事件)。
- 示例代码:
// 2.4.1 on 简单注册事件 支持同时,不支持动态
$("div").on("click mouseenter", function () {
console.log(555);
});
$("#btn").click(function () {
var $newDiv = $("<div>box1</div>");
$("body").append($newDiv);
});
on 注册事件委托
- 特点:支持同时注册多个事件,并且支持动态绑定。通过指定第二个参数为要绑定事件的子元素选择器,实现事件委托。
- 示例代码:
// 2.4.2 on 委托注册事件 支持同时,支持动态
$("body").on("click mouseenter", 'div', function () {
console.log(666);
});
$("#btn").click(function () {
var $newDiv = $("<div>box1</div>");
$("body").append($newDiv);
});
3. 事件解绑
- unbind 方式(不推荐使用):
- 语法:
$(selector).unbind();
:解绑匹配元素所有的事件。$(selector).unbind('click');
:解绑匹配元素指定的click
事件。
- 示例代码:
- 语法:
$("div").unbind(); // 解绑所有事件
$("div").unbind('click'); // 解绑 click 事件
- undelegate 方式(不推荐使用):
- 语法:
$(selector).undelegate();
:解绑匹配元素所有的delegate
事件。$(selector).undelegate('click');
:解绑匹配元素指定的click
委托事件。
- 示例代码:
- 语法:
$("body").undelegate(); // 解绑所有委托事件
$("body").undelegate('click'); // 解绑 click 委托事件
- off 方式(推荐使用):
- 语法:
$(selector).off();
:解绑匹配元素所有的事件。$(selector).off('click');
:解绑匹配元素指定的click
事件。
- 示例代码:
- 语法:
$("div").off(); // 解绑所有事件
$("div").off('click'); // 解绑 click 事件
4. 触发事件
可以在满足一定条件后,用代码的方式触发事件。
click()
方法:专门用于触发click
事件。trigger()
方法:可以触发指定的事件,包括自定义事件。- 示例代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>触发事件</title>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
</head>
<body>
<button id="btn1">触发事件按钮</button>
<div>这是一个 div</div>
<script>
$(function () {
// 需求:当点击三次触发事件按钮后,给 div 添加鼠标移入事件
$("div").on("msg", function () {
console.log("msg");
});
var i = 0;
$("#btn1").click(function () {
i++;
console.log(i);
if (i == 3) {
// $("div").click(); // 触发点击事件
$("div").trigger("msg"); // 触发自定义事件
}
});
});
</script>
</body>
</html>
5. 事件对象
jQuery 事件对象是 JavaScript 事件对象的一个封装,处理了不同浏览器之间的兼容性问题。事件对象会在注册事件时自动生成,用于记录事件触发时的一些信息,如鼠标坐标、按键信息等。
- 常用属性:
screenX
、screenY
:触发事件那一点,距离屏幕最左上角的值。clientX
、clientY
:触发事件那一点,距离可视区左上角的值(忽视滚动条)。pageX
、pageY
:触发事件那一点,距离页面最顶部的左上角的位置(会计算滚动条的距离)。keyCode
:按下的键盘代码。
- 常用方法:
stopPropagation()
:阻止事件冒泡,即阻止事件向上级元素传播。preventDefault()
:阻止事件的默认行为,如链接的跳转、表单的提交等。return false
:同时阻止事件冒泡和默认行为。
- 示例代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>事件对象</title>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
</head>
<body>
<a href="https://www.example.com">点击我</a>
<script>
$("a").on("click", function (e) {
// alert("我是 a 的点击事件");
// e.stopPropagation(); // 阻止冒泡事件
e.preventDefault(); // 阻止默认行为
// return false; // 即可阻止冒泡事件,又可阻止默认行为
});
$(document).on("keydown", function (e) {
console.log(e.keyCode);
});
</script>
</body>
</html>