切换仅animation-direction不同的类时CSS动画仅运行一次的原因
解决CSS动画切换时直接跳转无过渡的问题
你的问题出在浏览器的DOM操作合并机制上:当你同步移除旧类、添加新类时,浏览器会把这两个操作合并到同一帧里执行,相当于直接从forward切换到backward(或者反过来),没有中间的“无动画状态”,导致动画引擎认为不需要重新触发动画。而调试时逐行执行,操作之间有时间间隔,浏览器有机会渲染出移除类后的状态,所以动画能正常运行。
解决方案:把添加类的操作延迟到下一帧执行
可以用setTimeout或者requestAnimationFrame,让浏览器先完成移除类的渲染,再添加新类触发动画。修改你的f函数即可:
function f() { var div = document.getElementsByTagName("div")[0]; t(div); // 用setTimeout把添加类的操作放到下一帧 setTimeout(() => { if (b) { forward(div); } else { backward(div); } b = !b; }, 0); }
或者更精准的requestAnimationFrame(推荐,和浏览器渲染周期同步):
function f() { var div = document.getElementsByTagName("div")[0]; t(div); requestAnimationFrame(() => { if (b) { forward(div); } else { backward(div); } b = !b; }); }
原理说明
延迟执行添加类的操作,会让浏览器先处理完移除类的DOM变更,完成一次重排重绘,此时元素回到初始的无动画状态,再添加新类时,动画引擎会检测到状态变化,重新触发动画效果。
另外,也可以简化你的CSS,把公共的动画属性抽离出来,只切换animation-direction,代码会更简洁:
div { width: 100px; height: 100px; background-color: red; /* 公共动画属性 */ animation-name: demo; animation-duration: 1s; animation-fill-mode: forwards; animation-timing-function: ease; } div.forward { animation-direction: normal; } div.backward { animation-direction: reverse; }
这样修改后,后续点击就能正常触发来回动画了。
内容的提问来源于stack exchange,提问作者Enbidi
相关产品推荐
相关产品推荐

