标签需手动设置 value 属性才能更新进度,其默认值为0且不自动响应外部变化;应通过JS同步更新 element.value,结合 onprogress 事件或流式读取获取真实进度数据。

<progress></progress> 标签本身不会自动更新进度,它只是个“哑”展示控件——你必须手动设置 value 属性才能让它动起来。
为什么
浏览器渲染时,<progress></progress> 默认 value 为 0(即使没显式写),且不会监听任何外部变化。它不和 JS 变量绑定,也不读取 CSS 动画帧或定时器。
- 常见错误:只写
<progress max="100"></progress>,没设value,结果永远显示 0% - 正确做法:用 JS 每次更新任务进度后,同步赋值给
element.value - 注意:直接改
innerHTML或用setAttribute('value', n)也行,但.value = n更快、更可靠
如何让进度条随 fetch / Promise 任务实时更新?
HTTP 上传/下载进度不能靠 <progress></progress> 自己感知,得靠 XMLHttpRequest 的 onprogress 事件,或 fetch + ReadableStream(较新,兼容性需查)。
- 上传场景(推荐
XMLHttpRequest):监听upload.onprogress,计算event.loaded / event.total,再写入progressEl.value - 下载场景(
fetch):目前无原生 progress 事件,需用response.body.getReader()分块读取,累加已读字节数 - 避免高频更新:不要每毫秒都设
value,可用requestAnimationFrame节流,或只在变化 ≥ 1% 时更新
value 和 max 的单位与精度问题
<progress></progress> 的 value 是纯数值,不带单位;百分比是浏览器自动算的(value / max × 100%),所以 max 不一定非得是 100。
- 用
max="1"+value="0.73"等小数,适合浮点型任务(如文件解析完成度) - 用
max="2489"+value="1956",适合计数类任务(如“已处理 1956/2489 条数据”),避免除法舍入误差 - 如果
value > max,进度条会显示“已完成”,但视觉上可能溢出(取决于 UA 样式);value 则不渲染进度(留白)
真正难的不是怎么让进度条动,而是怎么拿到那个“当前进度”的准确数值——它往往藏在异步逻辑深处,比如解压库的回调、Canvas 渲染循环的帧计数、或者 Web Worker 发来的 postMessage。别只盯着 <progress></progress>,先理清你的数据源在哪。

















