如何实现点击元素时重复触发CSS动画?
解决CSS动画无法重复触发的问题
你的问题核心在于初始动画设置了infinite循环,导致第一次点击启动动画后,它会一直循环下去,后续点击无法让动画从头开始执行。下面提供两种简单可行的解决方案:
方案一:用CSS类控制动画(推荐)
这种方式更清晰,便于维护,通过添加/移除类来触发动画:
修改后的CSS
#macaco { background-color: orange; height: 70px; width: 40px; transform: translateX(15vw); position: absolute; bottom: 22px; } /* 将动画逻辑抽离到单独的类中 */ .macaco-saltar { animation: linear saltar 1s forwards; } @keyframes saltar { 0% { transform: translatey(0px) translateX(15vw) } 50% { transform: translatey(-120px) translateX(15vw) } 100% { transform: translatey(0px) translateX(15vw) } }
修改后的JavaScript
const macaco = document.getElementById("macaco"); function saltar() { // 先移除动画类,避免重复添加无效 macaco.classList.remove("macaco-saltar"); // 强制浏览器触发重排,否则移除和添加操作会被合并,动画不生效 void macaco.offsetWidth; // 添加动画类,触发弹跳 macaco.classList.add("macaco-saltar"); } // 动画结束后自动移除类(可选,进一步确保状态干净) macaco.addEventListener("animationend", () => { macaco.classList.remove("macaco-saltar"); });
HTML无需修改,保持原有的点击绑定即可。
方案二:直接操作动画播放状态
如果你坚持使用animation-play-state,需要每次点击时重置动画到初始状态:
修改后的CSS
#macaco { background-color: orange; height: 70px; width: 40px; transform: translateX(15vw); position: absolute; bottom: 22px; animation: linear saltar 1s; animation-play-state: paused; } @keyframes saltar { 0% { transform: translatey(0px) translateX(15vw) } 50% { transform: translatey(-120px) translateX(15vw) } 100% { transform: translatey(0px) translateX(15vw) } }
修改后的JavaScript
const macaco = document.getElementById("macaco"); function saltar() { // 重置动画:先清空动画属性 macaco.style.animation = 'none'; // 触发重排,让浏览器感知到状态变化 void macaco.offsetWidth; // 重新设置动画并启动 macaco.style.animation = 'linear saltar 1s'; macaco.style.animationPlayState = 'running'; } // 动画结束后暂停,回到初始位置 macaco.addEventListener("animationend", () => { macaco.style.animationPlayState = 'paused'; });
关键原理说明
- 移除
infinite:因为我们需要的是单次触发的弹跳动画,而非无限循环。 - 强制重排:浏览器会合并DOM样式修改,
void macaco.offsetWidth会强制浏览器立即计算元素尺寸,确保重置动画的操作生效,让动画从头开始播放。
内容的提问来源于stack exchange,提问作者Janner
相关产品推荐
相关产品推荐

