如何实现hover over、click、hover out触发的三段动画按顺序完整执行?
实现按顺序触发的三段动画(hover over → click → hover out)
你找对方向了!jQuery的queue/dequeue确实是解决这种有序动画队列问题的核心工具,刚好能满足你「严格按顺序执行、重复触发不新增队列」的需求。我来给你拆解具体实现思路和代码:
核心思路
我们需要给目标元素创建一个自定义动画队列(避免和默认的fx动画队列冲突),把hover、click、hover out对应的三个动画步骤按规则加入队列,确保:
- 每个步骤只会被添加一次,重复触发不会堆积任务
- 上一个动画完成后才会启动下一个
- 严格遵循「hover over → click → hover out」的执行顺序
完整代码实现
// 给元素初始化一个自定义动画队列,命名为'animationQueue' $('#elem').queue('animationQueue', []); // Hover In 触发第一步动画 $('#elem').hover(function() { const $elem = $(this); const currentQueue = $elem.queue('animationQueue'); // 检查队列里是否已经存在第一步,避免重复添加 const hasStepOne = currentQueue.some(task => task === 'stepOne'); if (!hasStepOne) { // 将第一步动画加入队列 $elem.queue('animationQueue', 'stepOne', function(next) { // 这里替换成你的第一步动画逻辑,比如: $elem.animate({ opacity: 0.5 }, 2000, function() { console.log('第一步hover over动画完成'); next(); // 必须调用next(),队列才会执行下一个任务 }); }); // 如果队列之前是空的,手动启动队列 if (currentQueue.length === 0) { $elem.dequeue('animationQueue'); } } }, function() { // Hover Out 触发第三步动画 const $elem = $(this); const currentQueue = $elem.queue('animationQueue'); // 检查:队列里没有第三步,且已经有第二步(确保顺序正确) const hasStepThree = currentQueue.some(task => task === 'stepThree'); const hasStepTwo = currentQueue.some(task => task === 'stepTwo'); if (!hasStepThree && hasStepTwo) { // 将第三步动画加入队列 $elem.queue('animationQueue', 'stepThree', function(next) { // 这里替换成你的第三步动画逻辑,比如: $elem.animate({ opacity: 1 }, 2000, function() { console.log('第三步hover out动画完成'); next(); // 所有动画完成后清空队列,方便下次触发新序列 $elem.clearQueue('animationQueue'); }); }); } }); // Click 触发第二步动画 $('#elem').click(function() { const $elem = $(this); const currentQueue = $elem.queue('animationQueue'); // 检查队列里是否已经存在第二步,且已经有第一步(确保顺序正确) const hasStepTwo = currentQueue.some(task => task === 'stepTwo'); const hasStepOne = currentQueue.some(task => task === 'stepOne'); if (!hasStepTwo && hasStepOne) { // 将第二步动画加入队列 $elem.queue('animationQueue', 'stepTwo', function(next) { // 这里替换成你的第二步动画逻辑,比如: $elem.animate({ transform: 'scale(1.2)' }, 2000, function() { console.log('第二步click动画完成'); next(); // 启动下一个队列任务 }); }); } });
关键细节说明
- 自定义队列:用
animationQueue而不是默认的fx队列,避免和元素上的其他动画(比如默认的animate)冲突 - 去重检查:每次添加任务前判断队列里是否已经存在该步骤,防止重复hover/click时堆积任务
- 顺序控制:添加第二步时检查第一步是否存在,添加第三步时检查第二步是否存在,严格保证执行顺序
next()调用:每个动画完成后必须调用next(),否则队列会停滞,后续任务不会执行- 清空队列:第三步完成后清空自定义队列,确保下次触发时能重新开始新的动画序列
符合你预期的场景测试
比如每个动画时长2秒:
- 用户hover over元素1秒后点击 → 第一步动画继续执行完剩余1秒,然后自动启动第二步动画
- 用户再hover out → 第二步动画完成后,自动启动第三步动画
- 总时长刚好6秒,三段动画依次完整执行,中间重复触发不会打乱队列
内容的提问来源于stack exchange,提问作者Jonathan Yan
相关产品推荐
相关产品推荐

