You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

切换仅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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 22:01:16