在做上傳文件的時候,想要在上傳時把每個文件的進度條顯示出來,於是找到了addEventListener這個方法,這里記錄一下在實現進度條的過程中遇到的坑。
直接上JS代碼
var files = $("#upload")[0].files for (var i = 0; i < files.length; i++ ) { var formData = new FormData(); formData.append("file", files[i]); $.ajax({ url: url, type: 'POST', data: formData, processData: false, contentType: false, xhr: function() { var xhr = new XMLHttpRequest(); //使用XMLHttpRequest.upload監聽上傳過程,注冊progress事件,打印回調函數中的event事件 xhr.upload.addEventListener('progress', function(e){ var progressRate = Math.round((e.loaded / e.total) * 100) + '%'; //通過設置進度條的寬度達到效果 console.log(`fileName:', files[i].name, uploaded:', progressRate); }); return xhr; }, success: function (arg) { console.log(arg) }, error : function (responseStr) { console.log(responseStr.responseJSON) continue } }); }
出現的問題:
剛開始用以上代碼執行上傳多個文件,:xhr 中的 files[i].name 不正確,例如我上傳文件 a.jpg b.jpg c.jpg ,最后的輸出結果都是 fileName:c.jpg uploaded: xx%
原因是:
xhr:中的 files[i].name 受循環的影響,無論有循環多少次,這里的i總是顯示最后循環的一個數。
解決方法一:
將for循環中的var i 換成 let i,這樣在下面的循環中,每個循環都會使用各自的i,不會受循環的影響從而改變i的值。
解決方法二:
把 ajax 的代碼放在一個閉包里,將i作為參數傳入。
var files = $("#upload")[0].files for (var i = 0; i < files.length; i++ ) { function upload(){ var formData = new FormData(); formData.append("file", files[i]); function close(i){ $.ajax({ url: url, type: 'POST', data: formData, processData: false, contentType: false, xhr: function() { var xhr = new XMLHttpRequest(); xhr.upload.addEventListener('progress', function(e){ var progressRate = Math.round((e.loaded / e.total) * 100) + '%'; //通過設置進度條的寬度達到效果 console.log(`fileName:', files[i].name, uploaded:', progressRate); }); return xhr; }, success: function (arg) { console.log(arg) }, error : function (responseStr) { console.log(responseStr.responseJSON) } }); } return close } close = upload(); close(i); }