管理多文件上传的进度条

3
我正在使用ajax上传多个文件。一切似乎都工作得很好……我只是无法让我的进度条起作用……
任何帮助将不胜感激。谢谢。
var images = document.getElementById('images');
for(var i=0;i<images.files.length;i++) {
    var formData = new FormData();
    var image = images.files[i];
    formData.append('image', image);
    formData.append('order_id', document.getElementById('order_id').value);

    var xmlhttp=new XMLHttpRequest();
    xmlhttp.open("POST","/pictures/uploadImage");
    xmlhttp.send(formData);
    xmlhttp.upload.addEventListener('progress', function(e){
        document.getElementById("image_"+i+"_progress").value = Math.ceil(e.loaded/e.total)*100;
    }, false);
}

我基本上是单独上传图像.. 我觉得这样可以更好地跟踪进度条... 也许还有其他方法。

3个回答

3
根据 [MDN][1] 的说法:
请注意:在调用请求的open()之前,您需要添加事件监听器。否则,进度事件将不会触发。
因此,结合Engin的答案,您可以像这样操作:
const images = document.getElementById('images');
const completedCount = 0; // added for loadend scenario
const length = images.files.length;

for (let i = 0; i < length; i++) {
    const formData = new FormData();
    const image = images.files[i];
    formData.append('image', image);
    formData.append('order_id', document.getElementById('order_id').value);

    const xmlhttp = new XMLHttpRequest();
    (elId => {
        xmlhttp.upload.addEventListener('progress', e => {
            document.getElementById('image_' + elId + '_progress').value = Math.ceil(e.loaded / e.total) * 100;
        }, false);
    })(i); // to unbind i.

    // --- added for loadend scenario. ---
    xmlhttp.addEventListener('loadend', () => {
        completedCount++;
        if (completedCount == length) {
            // here you should hide your gif animation
        }
    }, false);
    // ---
    xmlhttp.open('POST', '/pictures/uploadImage');
    xmlhttp.send(formData);
}

更新:

要捕获所有文件上传完成的事件,您可以使用loadend事件。我已更新我的代码(请参见评论),但我不确定这是否是正确的方法。 [1]: https://developer.mozilla.org/zh-CN/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest#%E7%9B%91%E6%8E%A7%E8%BF%9B%E5%BA%A6


运行得非常好,谢谢。 - sarovarc
我有一个后续问题,假设我正在上传8个文件,如何构建一个事件监听器,在所有这些文件上传完成后触发。基本上,我将用一个加载gif替换我的提交按钮。一旦所有文件都上传完毕,我想停止那个加载gif,并用一些东西来代替它,显示“完成”。谢谢。 - sarovarc
我已经更新了我的答案,虽然我不确定这是否是最佳方法,也没有测试过。 - Ilya Luzyanin

1
我没有尝试过,但我认为它可以运行,因为for循环在您发布之前完成,而“i”的值等于images.files.length。对于糟糕的英语,我感到抱歉。
尝试这个:
var images = document.getElementById('images');

for(var i=0;i<images.files.length;i++) {
    getProgress(images.files[i],i); 
}

function getProgress(image,order){
    var formData = new FormData();
    formData.append('image', image);
    formData.append('order_id', document.getElementById('order_id').value);

    var xmlhttp=new XMLHttpRequest();
    xmlhttp.open("POST","/pictures/uploadImage");
    xmlhttp.send(formData);
    xmlhttp.upload.addEventListener('progress', function(e){
        document.getElementById("image_"+order+"_progress").value = Math.ceil(e.loaded/e.total)*100;
    }, false);
}

0

你可以包含另一个函数。

function upload(ProgressbarId){

    /*
     .
     .
     .
     some code
    */

    xmlhttp.upload.addEventListener("progress", function(evt){uploadProgress(evt,ProgressbarId);}, false);

}


function uploadProgress(evt,ProgressbarId) {

    if (evt.lengthComputable) {
        var percentComplete = Math.round(evt.loaded * 100 / evt.total);
        set_Progressbar(ProgressbarId,percentComplete);
    }
}

}


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接