【问题标题】:HTML5 file uploading with multiple progress bars带有多个进度条的 HTML5 文件上传
【发布时间】:2011-10-07 09:50:33
【问题描述】:

我正在通过 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”没有被“progress”事件正确读取。我怀疑我必须做某种绑定来告诉“进度”事件使用特定变量,因为它是“li”,但我不确定我错过了什么。

【问题讨论】:

    标签: html file-upload progress-bar


    【解决方案1】:

    您的示例无法正常工作,因为您没有考虑到在所有列表项都已创建时会触发 xhr 进度事件。但是,有很多方法可以使您的示例工作。这个想法是让 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);
    

    【讨论】:

      【解决方案2】:

      我想我找到了解决这个问题的方法。它看起来适用于我的一些测试。我的英语不太好,所以我只会分享我的示例脚本。如果您提出任何问题,我会尽力解释更多:)

      // 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);
      }
      

      【讨论】:

      • 太棒了,谢谢!我最初尝试将所有文​​件添加到数组中的队列中,但这不起作用。只是从文件输入中引用文件效果很好:D 你帮我创建了这个:userscripts.org/scripts/show/158420
      • 如本例所示,如果您想为每个文件设置单独的进度条,则必须为每个文件设置单独的 XHR,而不是在一个 XHR 中附加所有文件。我希望进度事件上有一些元数据,表明事件正在为哪个文件提供统计信息。
      • 对我来说不起作用 xhr.addEventListener("progress", function(e){}),必须使用 xhr.upload.onprogress = function(e){}
      • @Mehmet,我尝试运行您的代码,但进度条出现问题。它看到进度条处于一个循环中,它们开始增加,然后在 100% 之后开始减少回 0% 并保持,像 0% 到 100% 到 0% 一样来回移动。你能帮帮我吗?问候
      猜你喜欢
      • 2012-07-17
      • 2011-11-06
      • 2011-12-07
      • 2015-10-19
      • 1970-01-01
      • 2012-07-15
      • 1970-01-01
      • 2012-09-24
      相关资源
      最近更新 更多