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

如何使用JavaScript实现多组独立运行的环形进度条

修复多组环形进度条仅第一组生效的问题

你猜的没错,document.querySelectorAll返回的是节点列表(NodeList),直接访问它的innerText或style属性只会作用于列表里的第一个元素,加上所有进度条共用同一个定时器和计数器,导致只有第一组能正常动起来。

修复思路

给每个进度条单独创建动画逻辑,通过循环遍历节点列表,为每组进度条绑定独立的计数器、目标值和定时器:

  • 用forEach遍历节点列表,同时配对对应的进度条和数值元素
  • 每组进度条维护自己的起始值、目标值和定时器
  • 单独更新每组的文本内容和进度条样式

修复后的完整代码

HTML(无需修改)

<div class="container">
  <div class="circular-progress">
    <span class="progress-value">50</span>
  </div>
  <span class="text">HTML & CSS</span>
</div>
<div class="container">
  <div class="circular-progress">
    <span class="progress-value">67</span>
  </div>
  <span class="text">JavaScript</span>
</div>
<div class="container">
  <div class="circular-progress">
    <span class="progress-value">80</span>
  </div>
  <span class="text">React</span>
</div>

CSS(仅新增间距优化,核心样式不变)

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
  font-family: 'Poppins', sans-serif;
}

body {
  height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 20px; /* 新增:避免进度条挤在一起 */
  background: #7d2ae8;
}

.container {
  display: flex;
  width: 420px;
  padding: 50px 0;
  border-radius: 8px;
  background: #fff;
  row-gap: 30px;
  flex-direction: column;
  align-items: center;
}

.circular-progress {
  position: relative;
  height: 250px;
  width: 250px;
  border-radius: 50%;
  background: conic-gradient(#7d2ae8 3.6deg, #ededed 0deg);
  display: flex;
  align-items: center;
  justify-content: center;
}

.circular-progress::before {
  content: "";
  position: absolute;
  height: 210px;
  width: 210px;
  border-radius: 50%;
  background-color: #fff;
}

.progress-value {
  position: relative;
  font-size: 40px;
  font-weight: 600;
  color: #7d2ae8;
}

.text {
  font-size: 30px;
  font-weight: 500;
  color: #606060;
}

修改后的JavaScript

const circularProgressList = document.querySelectorAll(".circular-progress");
const progressValueList = document.querySelectorAll(".progress-value");
const speed = 10;

// 遍历每组进度条,创建独立动画
circularProgressList.forEach((circularProgress, index) => {
  const progressValue = progressValueList[index];
  let progressStartValue = 0;
  // 把文本转为数字作为目标值
  const progressEndValue = parseInt(progressValue.innerText);

  const progress = setInterval(() => {
    progressStartValue++;
    // 更新当前组的数值文本
    progressValue.textContent = `${progressStartValue}%`;
    // 更新当前组的进度条样式
    circularProgress.style.background = `conic-gradient(#7d2ae8 ${progressStartValue * 3.6}deg, #ededed 0deg)`;

    if (progressStartValue === progressEndValue) {
      clearInterval(progress);
    }
  }, speed);
});

关键修改点

  • 用forEach循环遍历所有进度条元素,确保每组都有独立的动画逻辑
  • 每组进度条单独存储自己的起始值和目标值,避免互相干扰
  • 操作DOM时,针对当前循环的元素(circularProgress和progressValue)进行修改,而不是整个节点列表

内容的提问来源于stack exchange,提问作者rnkwill

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 15:26:03