如何实现点击触发CSS @keyframes动画来回切换的功能?
实现点击切换的双向颜色动画
没问题!要实现点击切换动画(第一次点击灰→红→绿,再次点击绿→红→灰),咱们可以通过两种思路来搞定,我给你详细拆解一下:
方案一:双动画类+反向关键帧
这个思路最直观,给正向和反向动画分别定义类和关键帧,点击时切换对应的类即可。
第一步:HTML结构
先准备一个可点击的元素:
<div id="colorToggle">点击我切换颜色</div>
第二步:CSS样式
定义正向、反向动画的类和关键帧,别忘了加animation-fill-mode: forwards来保留动画结束后的状态:
/* 正向动画:灰色→红色→绿色 */ .animate-forward { animation-name: action-forward; animation-duration: 2s; animation-timing-function: linear; animation-fill-mode: forwards; /* 保持动画结束后的颜色 */ } /* 反向动画:绿色→红色→灰色 */ .animate-reverse { animation-name: action-reverse; animation-duration: 2s; animation-timing-function: linear; animation-fill-mode: forwards; } @keyframes action-forward { 0% { background-color: gray; } 50% { background-color: red; } 100% { background-color: green; } } @keyframes action-reverse { 0% { background-color: green; } 50% { background-color: red; } 100% { background-color: gray; } } /* 给元素加个默认样式,方便点击 */ #colorToggle { padding: 1rem; cursor: pointer; background-color: gray; /* 初始灰色 */ }
第三步:JavaScript逻辑
点击时判断当前状态,切换动画类,还要强制重绘确保动画能重新触发:
const toggleElement = document.getElementById('colorToggle'); let isGreen = false; toggleElement.addEventListener('click', () => { // 先移除所有动画类,避免冲突 toggleElement.classList.remove('animate-forward', 'animate-reverse'); // 强制浏览器重绘,否则连续点击可能不触发动画 void toggleElement.offsetWidth; if (isGreen) { // 当前是绿色,切换到反向动画 toggleElement.classList.add('animate-reverse'); isGreen = false; } else { // 当前是灰色,切换到正向动画 toggleElement.classList.add('animate-forward'); isGreen = true; } });
方案二:CSS变量+单关键帧
如果不想写重复的关键帧,可以用CSS变量动态修改动画的起始和结束颜色,更简洁:
CSS部分
#colorToggle { padding: 1rem; cursor: pointer; /* 定义初始颜色变量 */ --start-color: gray; --end-color: green; background-color: var(--start-color); } .animate { animation-name: toggle-action; animation-duration: 2s; animation-timing-function: linear; animation-fill-mode: forwards; } @keyframes toggle-action { 0% { background-color: var(--start-color); } 50% { background-color: red; } 100% { background-color: var(--end-color); } }
JavaScript部分
const toggleElement = document.getElementById('colorToggle'); let isGreen = false; toggleElement.addEventListener('click', () => { toggleElement.classList.remove('animate'); void toggleElement.offsetWidth; if (isGreen) { // 切换到反向:起始绿,结束灰 toggleElement.style.setProperty('--start-color', 'green'); toggleElement.style.setProperty('--end-color', 'gray'); isGreen = false; } else { // 切换到正向:起始灰,结束绿 toggleElement.style.setProperty('--start-color', 'gray'); toggleElement.style.setProperty('--end-color', 'green'); isGreen = true; } toggleElement.classList.add('animate'); });
两种方案都能实现你要的切换效果,选哪个看你喜好:方案一逻辑清晰,适合动画步骤有差异的场景;方案二更简洁,减少代码重复。
内容的提问来源于stack exchange,提问作者Jeanluca Scaljeri
相关产品推荐
相关产品推荐

