基于HTML数据创建圆形进度条遇循环类型错误求助
圆形进度条遍历元素报错的解决方案
问题现象
单个圆形进度条元素可正常运行,但遍历所有元素时抛出错误:
Uncaught TypeError: Cannot read properties of undefined (reading 'start')
错误原因分析
- 类名选择器使用错误:
document.getElementsByClassName()的参数不需要添加.,原代码中带.的类名无法正确匹配元素,导致获取空集合。 - 集合属性访问错误:
valueContainer是HTMLCollection元素集合,不能直接通过valueContainer.dataset.start访问属性,需遍历集合中的单个元素。 - 循环与定时器逻辑混乱:嵌套循环和错误的变量引用导致无法独立控制每个进度条的动画,变量作用域引发异常。
- 终止条件判断错误:原代码中进度值的终止判断时机不对,无法正确停止定时器。
修正后的完整代码
HTML(无需修改)
<section class="skill"> <div class="container"> <div class="skill-grid"> <div class="skill-card"> <div class="circular-progress"> <div class="value-container" data-start="0" data-progress="90">0</div> </div> <p>UI Design</p> </div> <div class="skill-card"> <div class="circular-progress"> <div class="value-container" data-start="0" data-progress="80">0</div> </div> <p>UI Design</p> </div> <div class="skill-card"> <div class="circular-progress"> <div class="value-container" data-start="0" data-progress="60">0%</div> </div> <p>UI Design</p> </div> <div class="skill-card"> <div class="circular-progress"> <div class="value-container" data-start="0" data-progress="50">0%</div> </div> <p>UI Design</p> </div> </div> </div> </section>
CSS(无需修改)
.skill .container { display: grid; align-items: center; } .skill-grid { display: grid; grid-template-columns: 190px 190px; grid-template-rows: 190px 190px; justify-content: center; column-gap: 2.5rem; row-gap: 100px; margin-right: 2rem; position: relative; } .skill-card { background-color: var(--white); width: 100%; height: 100%; display: flex; flex-direction: column; align-items: center; justify-content: center; cursor: pointer; flex: 1 1 6rem; border-radius: 0.5rem; transition: transform ease-in-out 0.3s; } .skill-card p { font-size: 1rem; font-weight: 600; text-align: center; padding-top: 10px; } .circular-progress { position: relative; height: 100px; width: 100px; border-radius: 50%; display: grid; place-items: center; } .circular-progress:before { content: ""; position: absolute; height: 90%; width: 90%; background-color: #ffffff; border-radius: 50%; } .value-container { position: relative; font-family: var(--main-font); font-size: 1.3rem; color: var(--bs-primary); font-weight: 600; }
JavaScript(修正后)
// 获取所有进度条和数值容器(注意类名前不要加.) const progressBars = document.getElementsByClassName('circular-progress'); const valueContainers = document.getElementsByClassName('value-container'); function initProgressBars() { // 遍历每个数值容器,对应处理单个进度条 for (let i = 0; i < valueContainers.length; i++) { const currentContainer = valueContainers[i]; const currentProgressBar = progressBars[i]; // 解析当前元素的data属性为数字 let currentValue = parseInt(currentContainer.dataset.start); const targetValue = parseInt(currentContainer.dataset.progress); // 启动当前进度条的动画定时器 const interval = setInterval(() => { currentValue++; // 更新数值显示 currentContainer.textContent = `${currentValue}%`; // 更新进度条的锥形渐变 currentProgressBar.style.background = `conic-gradient( #4d5bf9 ${currentValue * 3.6}deg, #cadcff ${currentValue * 3.6}deg )`; // 达到目标值时停止定时器 if (currentValue >= targetValue) { clearInterval(interval); } }, 30); } } // 页面加载完成后初始化进度条 window.addEventListener('load', initProgressBars);
修正说明
- 修正了
getElementsByClassName的参数格式,确保正确获取元素集合。 - 遍历每个元素单独处理,避免集合属性访问错误。
- 每个进度条对应独立的定时器,解决作用域冲突问题,实现独立动画。
- 调整终止条件判断逻辑,确保进度达到目标值时及时停止动画。
内容的提问来源于stack exchange,提问作者mahmoud refat
相关产品推荐
相关产品推荐

