在做上传文件的时候,想要在上传时把每个文件的进度条显示出来,于是找到了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);
}