前面详细讲过 mouseenter 和 mouseleave,也提到了它们有一对对应的“冒泡版本”——mouseover 和 mouseout。现在就来具体讲 mouseover()。
mouseover() 在鼠标指针进入元素边界时触发,这一点和 mouseenter() 一样。但两者的关键区别在于事件冒泡行为:mouseover 会冒泡,而 mouseenter 不会。这导致在包含嵌套结构的元素上,mouseover 的触发次数可能远超预期。
语法形式
触发 mouseover 事件:
$(selector).mouseover()
程序化地触发 mouseover 事件。
绑定 mouseover 事件:
$(selector).mouseover(function(event){
// 鼠标进入时执行的代码
})
给选中元素绑定 mouseover 事件。
基础示例:mouseover 和 mouseout 配合切换颜色
下面这个例子用 mouseover() 和 mouseout() 配对,实现段落背景色的悬停切换。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>mouseover 基础示例</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
</head>
<body>
<p style="padding:12px;cursor:pointer;font-weight:bold;">将鼠标移入移出这段文字</p>
<script>
$(document).ready(function(){
$("p").mouseover(function(){
$("p").css("background-color", "#a9dfbf");
});
$("p").mouseout(function(){
$("p").css("background-color", "#e67e22");
});
});
</script>
</body>
</html>
鼠标移入段落变绿色,移出变橙色。这个效果和之前用 mouseenter/mouseleave 实现的一模一样。因为段落里没有嵌套的子元素,mouseover 和 mouseenter 表现一致。差异要在嵌套结构里才会暴来。
进阶示例:嵌套结构中的 mouseover 行为
下面这个例子直观展示了 mouseover 的冒泡特性。外层是一个绿色大容器,里面嵌套了一个红色小容器和一段提示文字。给外层容器绑定 mouseover 和 mouseout 事件。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>mouseover 嵌套结构示例</title>
<script src="https://code.jquery.com/jquery-1.10.2.js"></script>
<style>
.outer-box {
width: 60%;
height: 140px;
margin: 0 15px;
background-color: #a9dfbf;
position: relative;
}
.inner-box {
width: 60%;
height: 60%;
background-color: #e74c3c;
margin: 10px auto;
}
.status-text {
padding: 20px;
display: inline-block;
}
</style>
</head>
<body>
<div class="outer-box">
<span class="status-text" style="padding:20px;">移动鼠标到这里</span>
<div class="inner-box"></div>
</div>
<script>
$("div.outer-box")
.mouseover(function(){
$(this).find("span.status-text").text("mouse over 触发");
})
.mouseout(function(){
$(this).find("span.status-text").text("mouse out 触发");
});
</script>
</body>
</html>
操作一下就会发现:鼠标从外面进入绿域,提示文字变成“mouse over 触发”——这符合预期。但当鼠标从绿域滑到中间红色方块上时,提示文字会先闪一下“mouse out 触发”然后立刻变回“mouse over 触发”。这就是 mouseover 冒泡机制导致的现象。
为什么会这样?当鼠标从外层容器移动到内部红色方块时,浏览器认为鼠标“离开”了外层容器(因为进入了子元素),于是外层容器的 mouseout 被触发。紧接着,子元素的 mouseover 冒泡到外层,外层容器的 mouseover 又被触发。所以用户只是在内层移动了一下鼠标,外层的事件回调却执行了两次。
mouseenter 和 mouseover 怎么选
把这两者的差异清楚,选用时就不会纠结了:
| 特性 | mouseenter | mouseover |
|---|---|---|
| 触发时机 | 鼠标进入元素边界 | 鼠标进入元素边界 |
| 事件冒泡 | 不冒泡 | 会冒泡 |
| 进入子元素时 | 父元素不触发 | 父元素触发(冒泡导致) |
| 适用场景 | 大多数悬停交互 | 需要事件委托时 |
日常开发中,绝大多数悬停效果用 mouseenter/mouseleave 就够了。它们行为更符合直觉,不会因为嵌套子元素产生意外的反复触发。只有一种情况需要刻意用 mouseover/mouseout:当你需要利用事件冒泡机制做事件委托,把事件绑定在父容器上统一处理所有子元素的进出时。
本节课程知识要点
-
mouseover()在鼠标进入元素边界时触发,和mouseenter()的触发条件相同。 -
核心区别在于事件冒泡:
mouseover会冒泡,mouseenter不会冒泡。 -
在包含嵌套子元素的结构中,
mouseover会在鼠标进入子元素时再次触发(冒泡导致)。 -
大多数悬停场景推荐使用
mouseenter/mouseleave,行为更稳定可预期。 -
mouseover/mouseout适合需要事件委托的场景,利用冒泡机制统一管理子元素事件。
mouseover() 和 mouseenter() 虽然看起来差不多,但冒泡行为上的差异决定了它们各自适合的场景。理解这个差异之后,之前在嵌套结构里遇到的那些“明明鼠标还在里面却触发了离开事件”的奇怪现象就有了解释。到此为止,鼠标事件的四对方法——mouseenter/mouseleave、mouseover/mouseout、mousedown/mouseup、click/dblclick——的关系已经理清了。再加上之前讲过的键盘事件和表单事件,jQuery 事件体系的核心内容基本都覆盖完整了。