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

如何为每张单独上传的图片实现0到100%的流畅进度条

实现单张图片依次上传并显示流畅进度条

需要通过独立的XMLHttpRequest上传多张图片,要求请求按顺序逐一执行,让进度条为每张上传的图片从0%平滑过渡到100%。

当前代码存在两个问题:

  • 循环中同时发起所有请求,导致进度条频繁闪烁、来回跳动,控制台所有finito日志在整个上传流程结束时同时出现;
  • 改用同步请求(ajax.open("POST", "a_pro_up.php", false))后,日志按顺序输出,但进度条完全无法工作。

解决方案

核心思路是在上一张图片上传完成后,再发起下一张的上传请求,避免同时触发多个请求干扰进度条。通过闭包保存文件列表和当前上传索引,利用load事件触发下一次上传。

修改后的完整代码:

<input type="file" class='inpfi' id='inpimg' multiple accept="image/jpeg">
<progress class='pbar' id='pbar' value='0' max='100'> 0% </progress>

<script>
// 假设urw是已定义的业务变量
inpimg.addEventListener('change', function(){
    const files = this.files;
    let currentIndex = 0;

    // 上传单张图片的逻辑封装
    function uploadNext() {
        if (currentIndex >= files.length) return; // 所有文件上传完成,终止流程

        const file = files[currentIndex];
        const fd = new FormData();
        fd.append('id', urw);
        fd.append('upimg', file);
        
        const ajax = new XMLHttpRequest();
        ajax.upload.addEventListener("progress", up_progress, false);
        ajax.addEventListener("load", function() {
            up_img_finito();
            currentIndex++;
            uploadNext(); // 当前图片上传完成,启动下一张上传
        }, false);
        
        // 每次上传新图前重置进度条为0
        pbar.value = 0;
        ajax.open("POST", "a_pro_up.php");
        ajax.send(fd);
    }

    // 启动第一张图片的上传流程
    uploadNext();
});  

function up_progress(e){
    const percent = (e.loaded / e.total) * 100;
    pbar.value = Math.round(percent);
}

function up_img_finito(){
    console.log('finito');
}
</script>

关键改动说明

  • 用闭包保存文件列表和当前上传索引currentIndex,避免全局变量污染;
  • 封装uploadNext函数实现链式上传:当前图片上传完成(load事件触发)后,自动启动下一张图片的上传;
  • 每次开始新图片上传前重置进度条为0,保证单张图片的进度从0%平滑增长到100%;
  • 保留异步请求模式,确保progress事件能正常触发(同步请求会阻塞主线程,导致浏览器无法更新UI);
  • 替换原代码中的jQuery语法为原生JS,避免不必要的依赖。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 19:32:37