2013-05-13 72 views
1

我正在开发一个带进度条的ajax上传,如果文件输入不是多个,没有问题,但我想开发一个多重ajax上传,并因此我创建了一个“for”循环,直到用户选择的文件数量为止。Ajax in for循环增量变量i值到总长度

当函数进入此处时,indice的值是len变量的值,为什么会发生这种情况?

myXhr.upload.addEventListener('progress', function(e) { progressHandlingFunction(e, '.prog'+(indice)) }, false); 

的完整代码:

<script type="text/javascript"> 
    $(document).ready(function(e){ 
     $('#uploader').submit(function(){ 
      var inpf = document.getElementById('files'); 
      var len = inpf.files.length; 
      //console.log(inpf, len);return false; 
      for(var i=0; i<len; i++){ 
       var indice = i; 
       $('div').append('<progress class="prog'+i+'" value="0"></progress><br />'); 
       var formData = new FormData(); 
       formData.append('image', inpf.files[i]); 
       $.ajax({ 
        url: 'upload1.php', //server script to process data 
        type: 'POST', 
        xhr: function() { // custom xhr 
         var myXhr = $.ajaxSettings.xhr(); 
         if(myXhr.upload){ // check if upload property exists 
          myXhr.upload.addEventListener('progress', function(e) { progressHandlingFunction(e, '.prog'+(indice)) }, false); // for handling the progress of the upload 
         } 
         return myXhr; 
        }, 
        //Ajax events 
        //beforeSend: beforeSendHandler, 
        success: function(data){ 
         completeHandler(data, '.prog'+i); 
        }, 
        //error: errorHandler, 
        // Form data 
        data: formData, 
        //Options to tell JQuery not to process data or worry about content-type 
        cache: false, 
        contentType: false, 
        processData: false, 
       }); 
      } 
      return false; 
     }); 
    }); 

    function progressHandlingFunction(e, klass){ 
     if(e.lengthComputable){ 
      $(klass).attr({value:e.loaded, max:e.total}); 
     } 
    } 

    function completeHandler(data, klass){ 
     $(klass).attr({value:0}); 
    } 
</script> 

在这里,你有的jsfiddle与例如: http://jsfiddle.net/Pgq9s/

+0

我没有看到任何错误。似乎运作良好。 – Christian 2013-05-13 11:50:56

回答

2

变量i的范围是整个函数,而不是for循环的特定迭代。在执行success回调函数时,for循环将完全执行,并且i将等于最终迭代后的值(如此i == len)。

使用一个立即调用的函数表达式创建关闭,该次迭代保存的i值:

for(var i=0; i<len; i++){ 
    var indice = i; 
    $('div').append('<progress class="prog'+i+'" value="0"></progress><br />'); 
    var formData = new FormData(); 
    formData.append('image', inpf.files[i]); 
    (function(index) { 
    $.ajax({ 
     url: 'upload1.php', //server script to process data 
     type: 'POST', 
     xhr: function() { // custom xhr 
      var myXhr = $.ajaxSettings.xhr(); 
      if(myXhr.upload){ // check if upload property exists 
       myXhr.upload.addEventListener('progress', function(e) { progressHandlingFunction(e, '.prog'+(index)) }, false); // for handling the progress of the upload 
      } 
      return myXhr; 
     }, 
     //Ajax events 
     //beforeSend: beforeSendHandler, 
     success: function(data){ 
      completeHandler(data, '.prog'+index); 
     }, 
     //error: errorHandler, 
     // Form data 
     data: formData, 
     //Options to tell JQuery not to process data or worry about content-type 
     cache: false, 
     contentType: false, 
     processData: false, 
    }); 
    })(i); 
} 
+0

您可以减小“包装”的大小,并立即进行评估,以生成“xhr”属性值的函数。 – sje397 2013-05-13 11:56:47

+0

@ sje397'xhr'函数不是唯一使用'i'的值的函数,它也被用在'success'回调函数中。即使情况并非如此,我不确定减少它会有什么好处。 – 2013-05-13 12:05:29

+0

够公平的。我想为了可读性,你希望这些东西尽可能小。我甚至会倾向于编写另一个采用索引的函数,并将传递给'$ ajax'的对象返回 - 只是为了便于阅读。 – sje397 2013-05-13 12:12:44

2

在循环开始大量Ajax请求的。一旦所有的请求开始,i是最大的。

然后ajax请求的结果开始进入,并执行您的success回调函数。当所有回调被执行时,i仍然是最大值。