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

如何点击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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 10:16:33