动态启停多个间隔循环:为页面进度圈配置定时器与过渡色
搞定进度圈的动态进度与颜色渐变更新
嘿,针对你提到的进度圈需求,我整理了一套实用的实现方案,直接就能上手用:
核心思路拆解
- 每个进度圈配一个独立定时器,保证各自的动画互不干扰
- 进度从0开始慢慢涨,直到达到元素
data-current-progress属性里的目标值 - 你的
ProgressColourTween颜色数组刚好派上用场——100种颜色对应0-100%的进度,完美匹配
原生JavaScript实现代码
// 先把页面上所有带进度属性的进度圈都捞出来 const progressCircles = document.querySelectorAll('[data-current-progress]'); progressCircles.forEach(circle => { // 拿到目标进度,转成数字 const targetProgress = parseInt(circle.dataset.currentProgress); // 当前进度从0开始 let currentProgress = 0; // 给每个进度圈开个定时器,定时更新 const updateTimer = setInterval(() => { // 每次涨1%,想更平滑的话可以改成0.5 currentProgress += 1; // 更新进度圈显示的百分比文本 circle.textContent = `${currentProgress}%`; // 根据当前进度选颜色——数组100个元素,索引0对应0%,99对应99%,100%就用最后一个 const colorIndex = Math.min(currentProgress, 99); circle.style.color = ProgressColourTween[colorIndex]; // 如果是SVG环形进度条,就改stroke颜色: // circle.querySelector('.progress-ring__circle').style.stroke = ProgressColourTween[colorIndex]; // 进度到目标值就停掉定时器,顺便把最终状态补准确 if (currentProgress >= targetProgress) { clearInterval(updateTimer); const finalColorIndex = Math.min(targetProgress, 99); circle.textContent = `${targetProgress}%`; circle.style.color = ProgressColourTween[finalColorIndex]; } }, 30); // 定时器间隔,毫秒数越小动画越流畅,自己根据性能调 });
几个要注意的细节
- 定时器独立性:用
forEach循环给每个进度圈单独创建定时器,不会出现多个进度圈抢节奏的情况 - 颜色匹配逻辑:刚好100种颜色对应0-100%,直接用当前进度当索引就行,记得处理100%时取数组最后一个元素,防止索引越界报错
- 动画平滑度:要是觉得1%的步长太跳,可以改成0.5%,同时把定时器间隔改成15ms,动画会细腻很多,但别调得太极端,不然可能影响页面性能
- 适配SVG进度圈:如果你的进度圈是SVG做的环形条,只需要把更新颜色的目标换成SVG里的stroke元素就行,逻辑完全通用
内容的提问来源于stack exchange,提问作者Tyler
相关产品推荐
相关产品推荐

