2011-07-18 32 views
8

Estoy cargando varios archivos a través de XmlHTTPRequest y HTML5. Tengo la carga funcionando bien, pero me gustaría tener una barra de progreso para cada carga de archivo. El código que tengo, sin embargo, usa la última barra de progreso para TODAS las cargas de archivos en lugar de cada carga usando su propia barra de progreso. Así que esto es principalmente visual en el lado del cliente, pero realmente me molesta. Por alguna razón, asumo que el evento que vincula el progreso de la carga del archivo se sobrescribe a sí mismo y utiliza la última barra de progreso. Aquí está mi código:Carga de archivos HTML5 con barras de progreso múltiples

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

Estoy asumiendo que el "Li" adecuado no está siendo leído correctamente por el evento "progreso". Sospecho que tengo que hacer algún tipo de encuadernación para decir al evento de "progreso" que use una variable en particular, ya que es "li", pero no estoy seguro de lo que me estoy perdiendo.

Respuesta

14

Su ejemplo no funciona correctamente, por supuesto, no tiene en cuenta que el evento de progreso xhr se activa cuando todos los elementos de la lista ya se han creado. Sin embargo, hay muchas maneras de hacer que tu ejemplo funcione. La idea es dejar que xhr sepa exactamente qué elemento está tratando. Por ejemplo utilizar este código (. Yo no comprobar si funciona El propósito de este código es describir la idea):

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

creo que he encontrado una solución para este problema. Parece que está trabajando en algunas de mis pruebas. No soy muy bueno en inglés, así que solo compartiré mi script de muestra. Si hace alguna pregunta, intentaré explicar más :)

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

¡Fantástico, gracias! Intenté originalmente agregar todos los archivos a una cola en una matriz, pero eso no funcionaría. Sin embargo, hacer referencia a los archivos de la entrada del archivo funciona muy bien: D Me ayudó a crear esto: http://userscripts.org/scripts/show/158420 – Pluto

+1

Como muestra este ejemplo, si desea tener barras de progreso separadas para cada archivo, debe tener un XHR separado para cada archivo en lugar de tener un XHR con todos los archivos adjuntos. Esperaba que el evento de progreso tuviera metadatos que indicaran en qué archivo estaba proporcionando estadísticas el evento. –

+0

Para mí no funcionó xhr.addEventListener ("progreso", función (e) {}), tuve que usar xhr.upload.onprogress = function (e) {} – maylon

Cuestiones relacionadas