带有多个进度条的HTML5文件上传

时间:2011-07-18 04:56:11

标签: html5 file-upload progress-bar

我通过XmlHTTPRequest和HTML5上传多个文件。我上传工作正常,但我希望每个文件上传都有一个进度条。但是,我的代码使用最后一个进度条进行所有文件上传,而不是使用自己的进度条进行每次上传。所以这主要是客户端的视觉效果,但它真的很烦我。出于某种原因,我假设附加文件上传进度的事件会覆盖自己并使用最后一个进度条。这是我的代码:

var files = event.dataTransfer.files;

    // iterate over each file to upload, send a request, and attach progress event
    for (var i = 0, file; file = files[i]; i++) {
        var li = $("<li>" + file.name + "<div class='progressbar'></div></li>");

        // add the LI to the list of uploading files
        $("#uploads").append(li);

        // fade in the LI instead of just showing it
        li.hide().fadeIn();

        var xhr = new XMLHttpRequest();

            xhr.upload.addEventListener('progress', function(e) {
                var percent = parseInt(e.loaded / e.total * 100);
                li.find(".progressbar").width(percent);
            }, false);

            // check when the upload is finished
            xhr.onreadystatechange = stateChange;

            // setup and send the file
            xhr.open('POST', '/attachments', true);
            xhr.setRequestHeader('X-FILE-NAME', file.name);
            xhr.send(file);
        }

我假设“进度”事件没有正确读取正确的“li”。我怀疑我必须做某种约束来告诉“进展”事件使用特定变量,因为它是“li”,但我不确定我缺少什么。

2 个答案:

答案 0 :(得分:16)

您的示例无法正常工作,因为您没有考虑在已创建所有列表项时触发xhr progress事件。但是,有很多方法可以使您的示例正常工作。我们的想法是让xhr知道它正在处理的确切列表项。例如,使用此代码(我没有检查它是否有效。此代码的目的是描述这个想法):

var xhr = new XMLHttpRequest();
xhr.upload.li = li;
xhr.upload.addEventListener('progress', function(e) {
    var percent = parseInt(e.loaded / e.total * 100);
    this.li.find(".progressbar").width(percent);
}, false);

答案 1 :(得分:7)

我想我找到了解决这个问题的方法。它看起来正在进行我的一些测试。我不太擅长英语,所以我只是分享我的样本脚本。如果您提出任何问题,我会尝试解释更多:)

// This is input object which type of file.  
var uploader = document.getElementById("fileUploader"); 

// We'll send a new post for each file.
for(var i=0, j=uploader.files.length; i<j; i++)
{
    var uploaderForm = new FormData(); // Create new FormData
    uploaderForm.append("action","upload"); // append extra parameters if you wish.
    uploaderForm.append("up_file",uploader.files[i]); // append the next file for upload

    var xhr = new XMLHttpRequest();

    xhr.addEventListener("loadstart", function(e){
        // generate unique id for progress bars. This is important because we'll use it on progress event for modifications
        this.progressId = "progress_" + Math.floor((Math.random() * 100000)); 

        // append progress elements to somewhere you want
        $("body").append('<div id="' + this.progressId + '" class="myCustomProgressBar" ></div>');
    });
    xhr.addEventListener("progress", function(e){
        var total = e.total;
        var loaded = e.loaded;
        var percent = (100 / total) * loaded; // Calculate percentage of loaded data

        // I animate progress object. Notice that i use "this.progressId" which i created on loadstart event.
        $("#" + this.progressId).animate({"width":300 * (percent / 100)}, 800);
    });

    xhr.open("POST","index.php");
    xhr.send(uploaderForm);
}