如果说 fadeIn() 负责元素的登台亮相,那么 fadeOut() 就是为元素编排的谢幕动作。它通过逐步降低元素的透明度,让可见元素平滑地过渡到透明状态,最终在动画完成后将元素的 CSS display 属性设为 none,使其彻底脱离文档流。
这个过程看似简单,但动画完成后自动设置 display: none 这一步,是 fadeOut() 和单纯用 CSS 改 opacity 的本质区别。如果只用 CSS 把透明度降到 0,元素仍然占据页面空间,仍然可以响应点击事件,这在交互层面存在隐患。fadeOut() 帮我们一并处理了这些收尾工作。
语法拆解
fadeOut() 的参数结构和 fadeIn() 对称,掌握一个就相当于掌握了另一个。
1. 无参数调用
$(selector).fadeOut();
以默认的 400 毫秒时长完成淡出。适合对速度没有特殊要求的常规场景。
2. 带时长和回调
$(selector).fadeOut(speed, callback);
-
speed:淡出过程的持续时间。预定义值
"slow"约 600 毫秒,"fast"约 200 毫秒,也可以传入具体毫秒数值。 -
callback:元素彻底淡出并设置
display: none后触发的函数。注意,回调是在动画真正结束后才执行,不是一开始就触发。
3. 带缓动函数的完整形式
$(selector).fadeOut(speed, easing, callback);
-
easing:控制透明度从 1 到 0 的变化速率曲线。默认
"swing"让淡出在中间阶段加速,结尾略缓,符合人眼对消失过程的感知习惯。
一个模拟关闭通知的实用示例
下面这个例子把三个不同颜色的消息框用不同的速度淡出,模拟用户在通知中心逐条关闭消息的场景。同时引入回调函数,在每条消息淡出后更新底部的计数提示。
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script>
$(document).ready(function(){
var remaining = 3;
$("#dismissBtn").click(function(){
// 三条消息分别以不同速度淡出
$("#notice1").fadeOut("fast", updateCounter); // 快速消失
$("#notice2").fadeOut("slow", updateCounter); // 中等节奏
$("#notice3").fadeOut(2000, updateCounter); // 缓缓隐去
});
function updateCounter(){
remaining--;
if (remaining > 0) {
$("#statusText").text("还有 " + remaining + " 条未读消息");
} else {
$("#statusText").text("所有消息已清除");
$("#dismissBtn").fadeOut(300);
}
}
});
</script>
<style>
.notice {
width: 340px;
padding: 14px 18px;
margin-bottom: 10px;
border-radius: 6px;
color: #fff;
font-family: Arial, sans-serif;
font-size: 14px;
}
#notice1 { background-color: #e67e22; } /* 橙色-普通通知 */
#notice2 { background-color: #9b59b6; } /* 紫色-提醒 */
#notice3 { background-color: #1abc9c; } /* 青色-系统消息 */
#dismissBtn {
padding: 8px 20px;
cursor: pointer;
margin-bottom: 15px;
}
#statusText {
color: #555;
font-size: 13px;
margin-top: 5px;
}
</style>
</head>
<body>
<button id="dismissBtn">一键清除通知</button>
<p id="statusText">还有 3 条未读消息</p>
<div id="notice1" class="notice">
<strong>新评论:</strong>有人在你的文章下发表了回复
</div>
<div id="notice2" class="notice">
<strong>提醒:</strong>你的订阅将在 7 天后到期
</div>
<div id="notice3" class="notice">
<strong>系统消息:</strong>你的账号于近期在异地登录
</div>
</body>
</html>
这里有几点值得留意。三条消息的淡出速度被有意错开——普通通知用 "fast" 迅速离场,系统消息用 2000 毫秒缓缓隐去,暗示了信息的优先级差异。回调函数 updateCounter 在每条消息淡出后都会执行一次,动态更新剩余条数。当计数归零时,连清除按钮自己也会淡出,给整个交互画上一个干净的句号。
fadeOut() 的常见与正确用法
本节课程知识要点:fadeOut() 在执行过程中只是降低透明度,元素占用的空间在动画期间不会释放。这意味着如果一个高 200 像素的元素正在淡出,它下方的元素不会提前上移,必须等淡出动画彻底完成、display: none 生效后,布局才会重新计算。如果你需要让元素在消失的同时释放空间,slideUp() 是更直接的选择;如果一定要用淡出,可以在回调里手动触发一次布局调整。
个人经验分享:在开发中,我最常踩的一个坑是快速连续点击导致的动画堆积。假设用户狂点一个删除按钮,每次点击都触发一次 fadeOut(400),这些动画会排队依次执行。但由于第一个 fadeOut 完成后元素已经 display: none,后续的 fadeOut 在隐藏元素上执行不会有任何视觉效果,回调却依然会触发,这就可能导致回调里的逻辑被执行多次。
解决方式并不复杂——在执行 fadeOut() 之前先调用 stop(true, true)。第一个 true 清空动画队列,第二个 true 让当前动画直接跳到结束状态。这样无论用户点击多快,只会执行一次完整的淡出和回调。
$("#deleteBtn").click(function(){
// 先停止当前动画并清空队列,再执行淡出
$("#targetItem").stop(true, true).fadeOut(400, function(){
$(this).remove(); // 淡出后从 DOM 中移除
});
});
为什么用 fadeOut() 而不是直接 hide():两者的终点一样——元素最终都会消失。但 fadeOut() 给了用户一个短暂的视觉缓冲期,大脑能感知到“这个东西正在消失”。而 hide() 是瞬间的,元素啪的一下就没了,用户可能会困惑“刚刚那个按钮去哪了”。在删除操作、提示关闭、弹窗消失这类场景中,哪怕只有 200 毫秒的淡出,也能大幅改善交互的自然感。反过来说,如果操作的触发源和消失对象在页面上距离很远,用户注意力不在那个区域,那直接用 hide() 也可以,不需要为淡出而淡出。
关于 speed 的一个小建议:淡出速度和淡入速度保持一致,是比较稳妥的做法。如果一个对话框用 300 毫秒淡入,用 800 毫秒淡出,用户会隐约觉得“关掉怎么比打开还慢”,这种不对称的节奏容易让人烦躁。保持进出速度一致,交互节奏会显得更协调。