JavaScript中如何让函数使用每次赋值不同的skillPercent处理元素?
解决圆形进度条共享百分比变量的问题
问题根源
- 全局变量污染:你的
skillPercent和percent都没有用let/const声明,属于全局变量。循环中每次赋值都会覆盖之前的值,所有fill函数里的定时器最终都会引用同一个全局的skillPercent,导致所有进度条都使用最后一次设置的百分比。 - 定时器清除错误:
clearInterval(item)是无效的,clearInterval需要传入定时器的ID,而非DOM元素,这会导致定时器无法被正确停止。
修正后的代码
const d = document.querySelectorAll(".divb"); let i = d.length; while (i--) { let skillPercent; // 用classList.contains替代className.includes,避免类名误匹配 if (d[i].classList.contains("1")) { skillPercent = 40; fill(d[i], skillPercent); } else if (d[i].classList.contains("2")) { skillPercent = 70; fill(d[i], skillPercent); } else if (d[i].classList.contains("3")) { skillPercent = 90; fill(d[i], skillPercent); } } // 将fill函数移到循环外,避免重复定义 function fill(item, targetPercent) { let percent = 1; // 保存定时器ID,用于后续清除 const timer = setInterval(() => { // 用>=判断避免步长导致的漏判 if (percent >= targetPercent) { clearInterval(timer); // 确保进度条最终停在目标百分比 item.style.background = `conic-gradient( #ff5555 ${targetPercent}%, #000 0%)`; return; } percent += 0.5; item.style.background = `conic-gradient( #ff5555 ${percent}%, #000 0%)`; }, 30); }
关键修改说明
- 块级作用域变量:给
skillPercent、percent、timer添加let/const声明,让每个进度条的变量独立,互不干扰。 - 传递目标百分比参数:将
targetPercent作为参数传入fill函数,每个进度条的填充逻辑持有自己的目标值,不再依赖外部变量。 - 优化类名判断:使用
classList.contains替代className.includes,避免类名包含数字的其他情况(比如类名10会被includes("1")误匹配)。 - 正确清除定时器:保存
setInterval返回的定时器ID,用它来调用clearInterval,确保定时器能被正确停止。 - 稳妥的终止条件:用
percent >= targetPercent替代percent == targetPercent,避免因步长精度问题导致定时器无法停止。
内容的提问来源于stack exchange,提问作者MaDragon7
相关产品推荐
相关产品推荐

