如何点击HTML&CSS实现的5秒倒计时器完成重置?
搞定点击重置倒计时的问题!
嘿,作为编程新手能拼出带动画的倒计时已经很棒啦!要实现点击重置,核心是让CSS动画能从头开始播放——毕竟默认动画跑完就停了,咱们得用JS来“重启”它。我给你调整了代码,一步步来:
核心思路
CSS动画一旦播放完就不会自动重启,所以我们要:
- 把动画从元素默认样式里抽成独立的类,方便用JS控制添加/移除
- 点击时先移除动画类,强制浏览器重绘后再重新添加,让动画从头开始
- 同时确保数字和进度条都同步重置
修改后的完整代码
HTML部分
我给关键元素加了ID,方便JS精准控制,同时保留了你的onclick事件:
<!DOCTYPE html> <html> <head> <style> /* 这里放修改后的CSS */ </style> </head> <body> <div id="countdown-container" class="countdown animate-num" onclick="myFunction()"> <svg viewBox="-50 -50 100 100" stroke-width="10"> <circle r="45" fill="none" stroke="silver"></circle> <circle id="progress-circle" r="45" fill="none" stroke-dasharray="282.7433388230814" stroke-dashoffset="282.7433388230814px" class="animate-arc"></circle> </svg> </div> <script> // 这里放myFunction()代码 </script> </body> </html>
CSS部分
我把原来直接写在元素上的animation属性抽成了单独的类,这样就能用JS开关动画:
.countdown { display: grid; margin: 1em auto; width: 5em; height: 5em; place-items: center; cursor: pointer; /* 加个鼠标指针提示可点击 */ } .countdown::after { grid-column: 1; grid-row: 1; place-self: center; font: 1em/2 ubuntu mono, consolas, monaco, monospace; content: "0:" counter(s, decimal-leading-zero); } /* 数字动画类 */ .animate-num { animation: num 5s steps(1) forwards; } @keyframes num { 0% { counter-reset: s 5; } 20% { counter-reset: s 4; } 40% { counter-reset: s 3; } 60% { counter-reset: s 2; } 80% { counter-reset: s 1; } 100% { counter-reset: s 0; } } svg { grid-column: 1; grid-row: 1; } #progress-circle { transform: rotate(-90deg); stroke-linecap: round; } /* 进度条动画类 */ .animate-arc { animation: arc 5s linear forwards, col 5s linear forwards; } @keyframes arc { 0% { stroke-dashoffset: 0px; } 100% { stroke-dashoffset: 282.7433388230814px; } /* 修正:原来的动画方向反了,这样进度条才会从满到空 */ } @keyframes col { 0% { stroke: #00ff00; } 25% { stroke: #bfff00; } 50% { stroke: #ffff00; } 75% { stroke: #ff8000; } 100% { stroke: #ff0000; } }
注意:我修正了
arc动画的100%状态——原来的写法是0%对应offset 0,这样进度条是从空到满,和数字倒计时反了,现在改成从0到282.74(也就是圆的周长),进度条会随着数字减少逐渐“清空”,逻辑更顺。
JS部分(myFunction()实现)
这就是重置的核心逻辑,注释已经写清楚了:
function myFunction() { const countdown = document.getElementById('countdown-container'); const progressCircle = document.getElementById('progress-circle'); // 1. 移除动画类,让动画停止并回到初始状态 countdown.classList.remove('animate-num'); progressCircle.classList.remove('animate-arc'); // 2. 强制浏览器重绘(必须加这一步,不然浏览器可能跳过移除直接加类,看不到重置效果) void countdown.offsetWidth; // 3. 重新添加动画类,触发动画从头播放 countdown.classList.add('animate-num'); progressCircle.classList.add('animate-arc'); }
为什么这么做?
- 移除动画类后,元素会回到没有动画的初始状态(数字显示5,进度条满)
void countdown.offsetWidth是个小技巧,让浏览器强制计算元素尺寸,触发重绘,这样再添加类的时候,浏览器会认为是新的动画,从头开始播放- 把动画抽成类,比直接修改元素的
animation属性更灵活、易维护
现在你点击倒计时的任何位置,都会立刻重置回5秒,动画从头开始跑啦!
内容的提问来源于stack exchange,提问作者J.C.11229
相关产品推荐
相关产品推荐

