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

如何移除CSS类时避免触发fade-in动画?

问题根源

问题出在.splash *的动画规则是持久绑定的——每次元素的动画属性从none(no_transition类)恢复时,浏览器会重新触发fade-in动画,因为它会重新应用这个默认动画规则。

下面是几种可行的解决方案:


方案1:让fade-in仅在元素首次渲染时触发

通过给已完成淡入的元素添加标记类,阻止后续样式变化时重新触发动画:

修改CSS

/* 仅给未完成淡入的元素应用动画 */
.splash *:not(.fade-completed) {
    animation: fade-in 1s ease-in forwards;
    opacity: 1;
}

@keyframes fade-in {
    0% { opacity: 0; }
    100% { opacity: 1; }
}

/* 保留原有error动画样式 */
.error {
    animation: shake 0.4s ease-in-out;
    border-color: red;
}

@keyframes shake {
    0% { transform: translateX(0); }
    25% { transform: translateX(-5px); }
    50% { transform: translateX(5px); }
    75% { transform: translateX(-5px); }
    100% { transform: translateX(0px); }
}

修改JS

// 页面加载完成后,给所有splash子元素绑定动画结束事件
document.addEventListener('DOMContentLoaded', () => {
    document.querySelectorAll('.splash *').forEach(el => {
        el.addEventListener('animationend', (e) => {
            // 仅监听fade-in动画结束事件
            if (e.animationName === 'fade-in') {
                el.classList.add('fade-completed');
            }
        }, { once: true }); // 事件仅触发一次
    });
});

// 简化err函数,移除no_transition相关逻辑
function err(elem, msg) {
    if (msg) alert(msg);
    elem.classList.add('error');
    elem.disabled = true;
    setTimeout(() => {
        elem.classList.remove('error');
        elem.disabled = false;
    }, 1000);
}

方案2:通过强制重绘避免触发默认动画

利用浏览器重绘机制,在移除no_transition前手动锁定动画状态:

修改CSS

.splash * {
    animation: fade-in 1s ease-in;
    opacity: 1;
}

@keyframes fade-in {
    0% { opacity: 0; }
    100% { opacity: 1; }
}

.error {
    animation: shake 0.4s ease-in-out forwards;
    border-color: red;
}

@keyframes shake {
    0% { transform: translateX(0); }
    25% { transform: translateX(-5px); }
    50% { transform: translateX(5px); }
    75% { transform: translateX(-5px); }
    100% { transform: translateX(0px); }
}

.no_transition {
    animation: none !important;
    transition: none !important;
}

修改JS

function err(elem, msg) {
    if (msg) alert(msg);
    elem.classList.add('error');
    elem.disabled = true;
    setTimeout(() => {
        elem.classList.add('no_transition');
        elem.classList.remove('error');
        elem.disabled = false;
        
        // 手动设置动画为none,强制浏览器重绘
        elem.style.animation = 'none';
        void elem.offsetWidth; // 触发重绘
        
        // 移除no_transition类,此时不会触发fade-in
        elem.classList.remove('no_transition');
        // 恢复默认样式(可选)
        elem.style.removeProperty('animation');
    }, 1000);
}

方案3:用animation-play-state控制动画

通过暂停已完成的淡入动画,避免后续触发:

修改CSS

.splash * {
    animation: fade-in 1s ease-in forwards;
    opacity: 1;
    animation-play-state: running;
}

@keyframes fade-in {
    0% { opacity: 0; }
    100% { opacity: 1; }
}

.error {
    animation: shake 0.4s ease-in-out;
    border-color: red;
    animation-play-state: running !important;
}

@keyframes shake {
    0% { transform: translateX(0); }
    25% { transform: translateX(-5px); }
    50% { transform: translateX(5px); }
    75% { transform: translateX(-5px); }
    100% { transform: translateX(0px); }
}

修改JS

document.addEventListener('DOMContentLoaded', () => {
    document.querySelectorAll('.splash *').forEach(el => {
        el.addEventListener('animationend', (e) => {
            if (e.animationName === 'fade-in') {
                // 淡入完成后暂停动画,阻止后续触发
                el.style.animationPlayState = 'paused';
            }
        }, { once: true });
    });
});

function err(elem, msg) {
    if (msg) alert(msg);
    elem.classList.add('error');
    elem.disabled = true;
    setTimeout(() => {
        elem.classList.remove('error');
        elem.disabled = false;
    }, 1000);
}

内容的提问来源于stack exchange,提问作者Blue Herring

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 16:57:17