SVG环形进度条无法按设定值完成进度的技术求助
SVG环形进度条无法根据指定数值显示进度的修复方案
问题根源
当前代码存在几个核心问题导致进度无法按指定数值显示:
- 混淆了目标数值和进度百分比的映射:把
data-degree当成了计数终点,而非要显示的进度百分比(比如75应该对应75%进度,而非计数到75就满格)。 - 全局DOM选择器冲突:用
document.querySelector选文本元素,多进度条时会出错。 - SVG元素属性误用:给
<circle>设置background,但SVG矢量元素不支持这个CSS属性,得用原生的stroke-dashoffset控制进度。 - 进度计算逻辑错误:直接用目标数值计算偏移量,而非当前进度的百分比。
修改后的完整代码
HTML
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Circular Progress Bar</title> </head> <body> <div class="center"> <div class="progress"> <svg class="progress-bar" data-degree="75" data-color="#0b60e9" width="300" height="300"> <circle class="progress-circle" cx="150" cy="150" r="135"></circle> <circle class="progress-circle progress-fill" cx="150" cy="150" r="135"></circle> </svg> <div class="text"> 0 <span>Completed</span> </div> <div class="totalfilling"> <h5>75</h5> </div> </div> </div> </body> </html>
CSS
body { width: 100%; height: 100vh; margin: 0; padding: 0; } .center { width: 100%; height: 100%; display: flex; align-items: center; justify-content: center; background: rgb(25, 25, 50); } .progress { width: 400px; height: 400px; background: rgb(255, 255, 255); border-radius: 5mm; display: flex; align-items: center; justify-content: center; position: relative; } circle { fill: none; } svg { transform: rotate(90deg); } .progress-circle:nth-child(1) { stroke: rgb(240, 248, 255); stroke-width: 12px; } .progress-fill { stroke-width: 16px; stroke-linecap: round; stroke-dasharray: 848; stroke-dashoffset: 848; } .text { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); font-family: poppins; font-size: 60px; color: rgb(78, 91, 205); font-weight: 500; display: flex; align-items: center; justify-content: center; flex-direction: column; } .text span { font-size: 14px; color: rgb(78, 91, 205); } .totalfilling { position: absolute; bottom: 20px; right: 20px; }
JavaScript
window.addEventListener("load", function(event){ let progressbars = document.querySelectorAll('.progress-bar'); progressbars.forEach(function(svg){ let currentProgress = 0; const targetPercent = parseInt(svg.getAttribute('data-degree')); const color = svg.getAttribute('data-color'); const progressFill = svg.querySelector('.progress-fill'); // 从当前进度条的父容器找文本元素 const progressContainer = svg.closest('.progress'); const numberElem = progressContainer.querySelector('.text'); const totalElem = progressContainer.querySelector('.totalfilling h5'); // 设置初始样式 progressFill.style.stroke = color; numberElem.style.color = color; totalElem.textContent = targetPercent; const interval = setInterval(function(){ currentProgress += 1; // 当达到目标百分比时停止 if(currentProgress > targetPercent){ clearInterval(interval); return; } // 计算当前进度的百分比(0-1) const progressRatio = currentProgress / 100; // 计算stroke-dashoffset:总长度 - 已填充长度 const dashOffset = 848 - (848 * progressRatio); progressFill.style.strokeDashoffset = dashOffset; // 更新文本显示 numberElem.firstChild.textContent = currentProgress; },50); }); });
关键修改点
- DOM结构规范:把文本元素从SVG内部移到外部容器,符合SVG标准,同时方便精准查找元素。
- 进度逻辑修正:明确
data-degree代表进度百分比,比如75就对应75%的环形填充,而非计数到75就满格。 - 精准元素选择:通过
closest('.progress')限定查找范围,避免多进度条时的元素冲突。 - SVG原生属性控制:改用
stroke-dashoffset控制环形进度,这是SVG环形进度条的标准实现方式,避免无效的CSS属性设置。 - 初始样式设置:提前设置进度条颜色和文本颜色,确保样式统一。
内容的提问来源于stack exchange,提问作者Vicky
相关产品推荐
相关产品推荐

