JavaScript实现进度条核心是动态更新width或transform: scaleX(),用requestAnimationFrame配合缓动函数实现60fps平滑动画,需校验计算安全、同步ARIA属性并兼顾无障碍与移动端适配。

JavaScript 实现进度条的核心是控制 width 或 transform: scaleX()
原生 JS 实现进度条不需要框架,关键在于动态更新 DOM 元素的宽度或缩放比例。最常用的是修改一个子容器(如 进度变化如果靠定时器硬推,容易卡顿、跳帧,尤其在页面负载高时。正确做法是用 function step(timestamp) {
if (!startTime) startTime = timestamp;
const progress = Math.min((timestamp - startTime) / duration, 1);
const eased = easeOutCubic(progress);
const width = current + (targetWidth - current) * eased; }
requestAnimationFrame(step);
} // 调用:animateProgress(document.querySelector('.bar'), 75); CSS 立即学习“Java免费学习笔记(深入)”; 进度值常来自异步请求的 实际项目里,进度条的「动起来」只是表象,真正难的是和业务逻辑对齐:上传中断后如何恢复?多阶段任务怎么嵌套?这些不在动画本身,而在状态管理的设计里。style.width,配合父容器的 overflow: hidden 实现视觉填充效果。
用 transform: scaleX() 更适合动画性能——它触发的是合成层,不触发重排(layout),尤其在频繁更新时更流畅。用
requestAnimationFrame 做平滑动画,别用 setTimeout 或 setInterval
requestAnimationFrame 驱动每一帧更新,配合缓动函数(easing)模拟真实感。function animateProgress(el, targetWidth, current = 0, startTime = null) {
const easeOutCubic = t => --t * t * t + 1;
const duration = 300; // ms
el.style.width = width + '%';
if (progress < 1) requestAnimationFrame(step);
requestAnimationFrame 与屏幕刷新率同步,通常 60fps,比 setTimeout(..., 16) 更可靠easeOutCubic 是常见收尾减速效果style.width 时注意单位('%' 或 'px'),漏写会失效CSS 动画仅适用于固定起止值,JS 控制更适合动态场景
@keyframes 可以实现脉冲、流动、渐变色等效果,但前提是进度值已知且不常变。比如加载中状态用「骨架动画」:background: linear-gradient(90deg, transparent, #e0e0e0, transparent) 配合 animation 横向移动,这和 JS 更新的「确定性进度条」用途不同,二者常共存。
width,需确保初始状态有 transition: width 0.3s ease-out,否则无动画transform: scaleX() 的 transition,老项目慎用常见坑:百分比计算错误、未处理小数、忽略无障碍
loaded / total,直接相除可能得 NaN 或 Infinity;显示时若保留过多小数(如 99.999999%),CSS 渲染会抖动;另外,缺少 aria-valuenow 等属性会让读屏软件无法识别进度。
const percent = total ? Math.round((loaded / total) * 100) : 0
Math.min(Math.max(percent, 0), 100) 防止超限(如网络波动导致 loaded > total)el.setAttribute('aria-valuenow', percent)
touch-action: none 防止拖拽进度条时触发页面滚动











