JavaScript动画逻辑无法实现:动画结束后设置navigationOpen为true失败
解决JavaScript动画结束后设置状态不生效的问题
我懂这种异步踩坑的感觉!问题出在动画是异步执行的——你调用renderSlideOutAnimation()之后,同步的if语句会立刻跑,而动画还在执行中,navigationOpen根本还没被设置,所以判断自然不对。核心思路是:把设置navigationOpen和后续依赖它的逻辑,放到动画真正结束的回调里,而不是同步跟着动画函数走。
下面分几种常见的动画实现场景给你具体方案:
场景1:用CSS Transition实现动画
如果你的动画是靠CSS的transition属性触发的,就监听元素的transitionend事件,在事件回调里完成状态设置和后续逻辑:
function renderSlideOutAnimation() { const navElement = document.querySelector('.navigation'); // 添加动画类,触发CSS transition navElement.classList.add('slide-out'); // 监听动画结束事件,{ once: true } 确保只触发一次 navElement.addEventListener('transitionend', () => { // 动画结束,设置状态 navigationOpen = true; // 在这里执行依赖navigationOpen的if逻辑 if (navigationOpen) { console.log('导航动画结束,已切换为打开状态!'); // 你的其他业务逻辑 } }, { once: true }); }
场景2:用Web Animations API实现动画
如果是用element.animate()这个原生API做动画,它返回的Animation对象有个finished Promise,可以用await或者.then()等待动画结束:
// 用async/await让代码更直观 async function renderSlideOutAnimation() { const navElement = document.querySelector('.navigation'); // 定义动画关键帧和配置 const slideAnimation = navElement.animate([ { transform: 'translateX(-100%)' }, { transform: 'translateX(0)' } ], { duration: 300, easing: 'ease-out', fill: 'forwards' // 动画结束后保持最后一帧状态 }); // 等待动画完全结束 await slideAnimation.finished; // 再设置状态 navigationOpen = true; // 执行你的if判断逻辑 if (navigationOpen) { // 这里写你要做的事情 } }
场景3:用requestAnimationFrame手动写动画循环
如果是自己用requestAnimationFrame逐帧控制动画,就在循环结束的判断里设置状态:
function renderSlideOutAnimation() { const navElement = document.querySelector('.navigation'); let currentX = -100; // 初始偏移量(百分比) const targetX = 0; const duration = 300; // 动画总时长(毫秒) const startTime = performance.now(); function animateFrame(currentTime) { const elapsed = currentTime - startTime; // 计算动画进度(0到1),用ease-out缓动让动画更自然 const progress = Math.min(elapsed / duration, 1); const easedProgress = 1 - Math.pow(1 - progress, 3); // 更新元素位置 currentX = -100 + (targetX - (-100)) * easedProgress; navElement.style.transform = `translateX(${currentX}%)`; if (progress < 1) { // 动画未完成,继续下一帧 requestAnimationFrame(animateFrame); } else { // 动画结束,设置状态+执行逻辑 navigationOpen = true; if (navigationOpen) { console.log('手动动画完成,导航已打开'); // 你的业务代码 } } } requestAnimationFrame(animateFrame); }
核心要点就是:不要在调用动画函数后立刻同步执行依赖navigationOpen的代码,必须等动画的异步流程完全结束后,再去设置状态和执行判断逻辑,这样才能保证navigationOpen的值是正确的。
内容的提问来源于stack exchange,提问作者ItzAmmar
相关产品推荐
相关产品推荐

