记录addEventListener获取上传文件进度的坑

本文记录在使用JavaScript实现上传文件时,通过addEventListener获取进度信息遇到的问题。当上传多个文件,xhr.files[i].name始终显示为最后一个文件名。原因在于循环中的变量污染。解决方案包括使用let替换var,或者将ajax请求置于闭包内,确保每次循环的独立性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值