在做上傳文件的時候,想要在上傳時把每個文件的進度條顯示出來,於是找到了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);
}
