2013-05-13 69 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仍然是最大值。