如何使用 Javascript 将循环变量传递给事件回调函数

How to pass cycle variable to event callback function using Javascript

我正在使用 XMLHttpRequest 同时上传多个文件。我希望每个文件都有自己的进度指示器。因此,当我获得要上传的文件数组时,我会在一个 for 循环中为每个文件启动上传,例如

for(var i=0; i<files.length; i++)                    
{
  // Create transfer object
  var xhr = new XMLHttpRequest();

  // Attach progress event handler
  xhr.addEventListener('progress', function(e) { showProgress .... });

 ....
}

问题是,如何将正确的 "i" 值传递给进度回调函数。如果我这样使用 "i":

  xhr.addEventListener('progress', function(e) { console.log(i); });

我总是得到最新的 "i" 值。如果这样定义它:

  xhr.addEventListener('progress', (function(i,e) { console.log(i); })(i));

我是对的,但是我从来没有得到事件对象 "e",所以我没有得到实际的进展。正确的定义方式是什么?

使用 xhr.upload.progress 而不是 xhr.progress

创建一个 IIFE,将 i 传递给 IIFE,创建具有 className "progress-"i 连接的新 progress 元素,更新当前进度元素 .valuee.loadedupload progress 事件中。另见

for(var i=0; i<files.length; i++) {
  // Create transfer object
  (function(curr) {
    // `i` : `curr`
    var xhr = new XMLHttpRequest();
    var progress = document.createElement("progress");
    progress.setAttribute("max", files[curr].size);
    document.body.appendChild(progress);
    progress.className = "progress-" + curr;
    // Attach progress event handler
    xhr.upload.addEventListener("progress", function(e) {
      // update current `progress` `value`
      document.querySelector(".progress-" + curr).value = e.loaded;
    });
    xhr.open("POST", "/path/to/server/");
    xhr.send(new FormData(files[curr]));
  }(i)); // pass `i` to IIFE
}

jsfiddle https://jsfiddle.net/ytedpcro/1/