点击触发的入场动画必须用js切换class实现,因css无播放控制机制;直接写animation会自动执行,正确做法是初始状态禁用动画,js添加含动画或transition的class来激活。

点击触发的入场动画,不能靠纯 CSS 实现——@keyframes 定义了动画,但没“播放键”;:hover 只能作用于自身,没法让按钮控制另一个元素。必须用 JS 切换 class,让 CSS 过渡或关键帧生效。
为什么直接写 animation 在元素上会立刻执行
常见错误是把动画写死在初始样式里,比如:
.box { animation: slide-in 0.4s ease-out; }
这样页面一加载,.box 就自动动一次,完全不响应点击。根本原因是 CSS 动画默认“一定义就播”,没有暂停/触发机制。
正确做法是:初始状态不启用动画,只定义好关键帧或过渡规则,靠 JS 添加一个带 animation 或 transition 的 class 来激活。
- 初始 class 不含动画声明(或显式设
animation: none) - 触发 class 单独定义
animation或transition属性 - JS 只负责添加这个 class,不操作内联样式
用 transition + class 切换实现入场更轻量
多数入场动画(如滑入、淡入、缩放)用 transition 比 @keyframes 更合适:代码少、性能好、天然支持反向(再点一次可还原)。
示例:点击按钮让 #target 从底部滑入
.target { opacity: 0; transform: translateY(100%); transition: opacity 0.3s, transform 0.3s; }
.target.active { opacity: 1; transform: translateY(0); }
JS 部分只需:
document.getElementById('triggerBtn').addEventListener('click', () => {
document.getElementById('target').classList.add('active');
});
- 避免用
classList.toggle()直接切换——如果用户快速连点,可能动画还没结束就又加 class,导致中断或错乱 - 想支持“再点关闭”,得监听
transitionend并手动管理状态,或用布尔变量锁住触发 -
transition对display无效,别试图用它控制显示/隐藏;改用opacity+visibility或transform
用 @keyframes + animationend 实现单次播放动画
需要“只播一次、不循环、不反向”的效果(比如弹跳、抖动),就得用 @keyframes,并靠 animationend 事件清理 class,防止重复点击失效。
@keyframes bounce { 0% { transform: scale(0.8); } 50% { transform: scale(1.2); } 100% { transform: scale(1); } }
.animate-bounce { animation: bounce 0.4s ease-out; }
JS 要做两件事:加 class 触发,播完后立刻移除
btn.addEventListener('click', () => {
const el = document.getElementById('target');
el.classList.add('animate-bounce');
el.addEventListener('animationend', () => {
el.classList.remove('animate-bounce');
}, { once: true });
});
- 必须加
{ once: true },否则每次动画结束都绑新监听器,内存泄漏 - 不要用
setTimeout延时移除 class——动画时长受系统负载、CSS 变量影响,不可靠 -
animationend在动画被取消(如 class 被提前移除)时不会触发,所以清理逻辑必须在事件回调里做
容易忽略的兼容性与性能细节
看似简单,但线上常出问题的地方往往不在动画本身:
- 目标元素初始位置要设
position: relative或absolute,否则transform可能引发布局偏移 - 移动端 Safari 对
transform: translateY()的渲染有延迟,建议加will-change: transform提前提示 - 如果动画元素是动态插入的 DOM,确保 JS 执行时它已挂载,否则
getElementById返回null - 大量元素同时触发动画时,别用
transition控制height——重排开销大,改用max-height或transform
真正卡住的,往往是 class 没加对、事件没清干净、或者初始状态和动画终点不一致导致“闪一下”。先检查这些,比调 easing 函数重要得多。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











