如何强制toggle淡入淡出过渡完成后再执行下一个?
解决快速hover切换时过渡动画丢失的问题
这个问题我太熟了!快速在按钮间hover时,CSS过渡还没跑完就被新的类切换操作打断,自然就丢失了淡入淡出效果。完全可以实现「等上一个动画做完再执行下一个」的需求,核心思路就是给动画加个「锁」——在动画进行时,拒绝触发新的类切换操作。
具体实现步骤
- 添加动画状态标记:用一个变量记录当前是否正在执行过渡动画,避免并发触发
- 监听过渡结束事件:利用
transitionend事件在动画完成后解锁状态 - 拦截并发触发:在hover事件触发时,先判断动画状态,锁定时直接跳过操作
修改后的代码示例
首先建议给四个按钮统一加一个类(比如.hover-trigger),并通过data-*属性绑定对应的目标类名,这样代码更简洁易维护:
<!-- 按钮示例 --> <button class="hover-trigger first-button" data-target="intro-2">按钮1</button> <button class="hover-trigger second-button" data-target="intro-3">按钮2</button> <button class="hover-trigger third-button" data-target="intro-4">按钮3</button> <button class="hover-trigger fourth-button" data-target="intro-5">按钮4</button>
// 初始化状态标记和目标元素 let isAnimating = false; const $intro = $('.intro'); // 统一绑定hover事件 $('.hover-trigger').hover(function() { // 如果正在动画,直接返回,不执行后续操作 if (isAnimating) return; // 锁定动画状态 isAnimating = true; // 获取当前按钮对应的目标类名 const targetClass = $(this).data('target'); // 执行类切换 $intro.toggleClass(targetClass); // 监听过渡结束事件,解锁状态(用one确保只触发一次) $intro.one('transitionend', function() { isAnimating = false; }); // 可选:加个兜底定时器,防止transitionend因异常未触发导致永久锁定 setTimeout(() => { isAnimating = false; }, 600); // 时间比你的过渡时长稍长,比如过渡是0.5s就设0.6s });
额外注意事项
- 确保你的CSS过渡属性设置正确,比如:
.intro { transition: background-image 0.5s ease; /* 注意:部分浏览器对background-image的过渡支持有限,如果效果不稳定,建议用伪元素叠加背景图+opacity过渡的方案 */ } - 如果你的过渡涉及多个属性,
transitionend会触发多次,这时候可以通过事件对象的propertyName判断是否是你关心的属性完成了过渡,比如:$intro.one('transitionend', function(e) { if (e.propertyName === 'background-image') { isAnimating = false; } });
内容的提问来源于stack exchange,提问作者macdan
相关产品推荐
相关产品推荐

