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

JS基于data属性修改SVG stroke-dashoffset并保留圆环动画

问题原因

代码不生效是三个核心错误导致的:

  • 定时器清除参数传错:clearInterval需要传入定时器ID,你传的是计数变量counters[index](数值类型),定时器永远不会被清除,会持续异常运行。
  • 偏移量计算逻辑错误:一是parseInt位置错误,number.dataset.num / 100本身是小数,直接转整数会丢失精度;二是你每次都用最终的data-num值计算偏移,没有和当前递增的计数器绑定,无法实现和数字同步的动画效果。
  • CSS动画优先级冲突:你给circle写死了anim动画,所有圆环动画终态都固定为stroke-dashoffset:70,CSS动画运行时的属性优先级会覆盖JS设置的内联样式,导致JS修改的值不生效。
修改方案

要保留数字递增+圆环进度同步的动画效果,按以下步骤调整:

  1. 删除CSS中写死终态的anim动画相关代码,避免覆盖JS动态设置的偏移值
  2. 修正JS中定时器清除的传参,传入正确的定时器ID
  3. 调整偏移量计算公式,和当前递增的计数值绑定,实现进度同步增长
  4. 提前把data-num的值转为数字,避免计算时的类型错误

修改后完整代码

JS部分

const numbers = document.querySelectorAll('.number');
const svgEl = document.querySelectorAll('svg circle');
const counters = Array(numbers.length).fill(0);
const intervals = Array(numbers.length);

numbers.forEach((number, index) => {
    // 提前拿到目标进度值,转成数字
    const target = parseInt(number.dataset.num);
    intervals[index] = setInterval(() => {
        if(counters[index] === target){
            // 传入正确的定时器ID清除任务
            clearInterval(intervals[index]);
        }else{
            counters[index] += 1;
            number.innerHTML = counters[index] + "%";
            // 用当前计数值计算实时偏移,和数字进度完全同步
            svgEl[index].style.strokeDashoffset = 472 * (1 - counters[index] / 100);
        }
    }, 20)
})

CSS部分(仅需调整circle相关样式)

/* 其余样式保持不变,只修改circle选择器的内容 */
circle {
    fill: none;
    stroke: #f75023;
    stroke-width: 20px;
    stroke-dasharray: 472;
    stroke-dashoffset: 472;
    /* 删除原有的animation属性,移除写死的anim动画 */
}

/* 完全删除原代码中@keyframes anim的整段动画定义 */

HTML部分

原有HTML不需要调整,JS运行时会自动覆盖.number里的初始文本,自动匹配data-num设置的目标值。


效果说明:页面加载后,数字会从0开始递增到data-num设置的目标值,同时圆环进度会同步从0增长到对应百分比,动画节奏和原有20ms间隔的流畅度保持一致,三个圆环会分别匹配90%、50%、70%的进度显示。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 14:42:24