上一篇讲了 mouseover(),它的搭档就是 mouseout()。mouseout() 在鼠标指针离开元素边界时触发,和 mouseleave() 的作用一样,但有一个关键差异——mouseout 会冒泡。
这两个“离开”事件的关系,和进入事件中 mouseover 与 mouseenter 的关系对称。mouseleave 不冒泡,只在鼠标真正离开元素边界时触发一次;mouseout 会冒泡,鼠标移动到内部子元素上时父元素也会触发 mouseout。这个差异在嵌套结构中影响很大,用错了方出现“鼠标明明还在里面,样式却跳回去了”的问题。
语法形式
触发 mouseout 事件:
$(selector).mouseout()
程序化地触发 mouseout 事件。
绑定 mouseout 事件:
$(selector).mouseout(function(event){
// 鼠标离开时执行的代码
})
给选中元素绑定 mouseout 事件。
基础示例:mouseover 和 mouseout 配合切换颜色
下面这个例子用 mouseover() 和 mouseout() 配对,实现段落背景色的悬停切换。移入变绿,移出变橙。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>mouseout 基础示例</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>
因为段落里没有嵌套的子元素,mouseout 和 mouseleave 的表现一致。这个简单的例子看不出区别,下面用嵌套结构来演示差异。
进阶示例:嵌套结构中的 mouseout 行为
下面这个例子直观展示了 mouseout 在嵌套元素中的冒泡行为。外层是一个绿色大容器,里面嵌套了一个红色小容器和一段提示文字。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>mouseout 嵌套结构示例</title>
<script src="https://code.jquery.com/jquery-1.10.2.js"></script>
<style>
.outer-container {
width: 60%;
height: 140px;
margin: 0 15px;
background-color: #a9dfbf;
position: relative;
}
.inner-block {
width: 60%;
height: 60%;
background-color: #e74c3c;
margin: 10px auto;
}
.status-label {
padding: 20px;
display: inline-block;
font-weight: bold;
}
</style>
</head>
<body>
<div class="outer-container">
<span class="status-label" style="padding:20px;">移动鼠标到这里</span>
<div class="inner-block"></div>
</div>
<script>
$("div.outer-container")
.mouseover(function(){
$(this).find("span.status-label").text("mouse over 触发");
})
.mouseout(function(){
$(this).find("span.status-label").text("mouse out 触发");
});
</script>
</body>
</html>
操作一下就能观察到区别。鼠标从外面进入绿色容器,提示变成“mouse over 触发”——正常。当鼠标从绿域滑到中间红色方块上时,提示文字瞬间变成“mouse out 触发”然后立刻又变回“mouse over 触发”。这就是 mouseout 冒泡的典型表现。
原因是:鼠标从外层容器进入内部红色方块时,浏览器判定鼠标“离开”了外层容器,于是触发了外层容器的 mouseout。紧接着红色方块的 mouseover 事件冒泡上来,又触发了外层的 mouseover。这一来一回导致提示文字闪变,而用户实际上并没有真正离开外层容器。
mouseleave 和 mouseout 怎么选
两对方法的差异如下:
| 特性 | mouseleave | mouseout |
|---|---|---|
| 触发时机 | 鼠标离开元素边界 | 鼠标离开元素边界 |
| 事件冒泡 | 不冒泡 | 会冒泡 |
| 离开到子元素时 | 父元素不触发 | 父元素触发(冒泡导致) |
| 适用场景 | 大多数悬停交互 | 需要事件委托时 |
日常开发里,需要鼠标离开效果的场景直接用 mouseleave 就够了。mouseout 的冒泡行为在嵌套结构中很容易造成意想不到的触发,除非你需要利用冒泡来做事件委托——比如在一个包含大量子元素的容器上统一监听所有子元素的离开事件,这时候 mouseout 的冒泡特性反而成了优势。
本节课程知识要点
-
mouseout()在鼠标离开元素边界时触发,和mouseleave()的触发条件相同。 -
核心区别在于事件冒泡:
mouseout会冒泡,mouseleave不会冒泡。 -
在包含嵌套子元素的结构中,
mouseout会在鼠标进入子元素时误触发(冒泡导致)。 -
大多数悬停场景推荐使用
mouseenter/mouseleave组合,行为更符合直觉。 -
mouseover/mouseout组合适合需要事件委托的场景,利用冒泡统一管理子元素事件。
mouseout() 是 mouseover() 的搭档,完成了会冒泡版本下鼠标离开的检测。它和 mouseleave 表面上只差一个字,但在嵌套结构中行为差异明显。到这里,鼠标事件的核心方法已经全部讲完——click、dblclick、mouseenter、mouseleave、mouseover、mouseout、mousedown、mouseup、hover——它们覆盖了从单击双击、进出悬停、按压松开到完整封装的各种鼠标交互场景。理解每个方法的触发时机和冒泡行为,写鼠标交互代码时的精准度会提升很多。