FileReader onload with result和parameter

时间:2014-12-02 16:52:55

标签: javascript filereader

我无法同时获得文件阅读器的结果和onload函数中的一些参数。这是我的代码:

控制HTML:

<input type="file" id="files_input" multiple/>

Javascript功能:

function openFiles(evt){
    var files = evt.target.files;
    for (var i = 0; i < files.length; i++) {
      var file=files[i];
      reader = new FileReader();
      reader.onload = function(){
          var data = $.csv.toArrays(this.result,{separator:'\t'});
      };
      reader.readAsText(file);
    }
  }

添加活动:

 files_input.addEventListener("change", openFiles, false);

我在filereader.result函数中使用onload。如果我为这个函数使用参数,比如file,我就不能再访问结果了。例如,我想在onload函数中使用file.name。如何解决这个问题?

6 个答案:

答案 0 :(得分:41)

尝试在另一个函数中包装onload函数。在这里,闭包使您可以通过变量f依次访问正在处理的每个文件:

function openFiles(evt){
    var files = evt.target.files;

    for (var i = 0, len = files.length; i < len; i++) {
        var file = files[i];

        var reader = new FileReader();

        reader.onload = (function(f) {
            return function(e) {
                // Here you can use `e.target.result` or `this.result`
                // and `f.name`.
            };
        })(file);

        reader.readAsText(file);
    }
}

有关为何需要关闭的讨论,请参阅以下相关问题:

答案 1 :(得分:6)

你应该在&#39; onload&#39;处理程序。 示例:http://jsfiddle.net/2bjt7Lon/

reader.onload = (function (file) { // here we save variable 'file' in closure
     return function (e) { // return handler function for 'onload' event
         var data = this.result; // do some thing with data
     }
})(file);

答案 2 :(得分:3)

事件处理是异步的,因此它们获取所有封闭局部变量的最新值(即闭包)。要将特定局部变量绑定到事件,您需要遵循上面用户建议的代码,或者您可以查看此工作示例: -

http://jsfiddle.net/sahilbatla/hjk3u2ee/

function openFiles(evt){
  var files = evt.target.files;
  for (var i = 0; i < files.length; i++) {
    var file=files[i];
    reader = new FileReader();
    reader.onload = (function(file){
      return function() {
        console.log(file)
      }
    })(file);
    reader.readAsText(file);
  }
}

#Using jQuery document ready
$(function() {
  files_input.addEventListener("change", openFiles, false);
});

答案 3 :(得分:2)

使用

var that = this;

访问函数范围内的外部变量。

function(){
    that.externalVariable //now accessible using that.___
}

我的场景-使用Angular 9。 我为此苦苦挣扎了很长时间,我似乎无法使它正常工作。 我发现以下内容是访问function()块内的外部变量的绝佳解决方案。

public _importRawData : any[];

importFile(file){
    var reader = new FileReader();
    reader.readAsArrayBuffer(file);

    var data;
    var that = this;  //the important bit

    reader.onloadend = await function(){
        //read data

        that._importRawData = data;  //external variables are now available in the function
    }

上面代码中的重要部分之一是var关键字,该关键字的作用域在功能块之外。 但是,当我在功能块之后访问data的值时,它仍未定义为在其他代码之后执行的函数。我尝试了异步并等待,但是无法正常工作。而且我无法在此功能之外访问data

最重要的是var that = this行。 使用可以在函数内部访问外部变量。因此,我可以在函数范围内设置该变量,而不必担心代码何时执行。读取后即可使用。

对于原始问题,代码为:

function openFiles(evt){
    var files = evt.target.files;
    for (var i = 0; i < files.length; i++) {
        var file=files[i];
      
        var that = this; //the magic happens
      
        reader = new FileReader();
        reader.onload = function(){
            var data = $.csv.toArrays(this.result,{separator:'\t'});
          
            that.file.name //or whatever you want to access.
        };
        reader.readAsText(file);
    }
}

答案 4 :(得分:0)

对于Typescript;

for (var i = 0; i < files.length; i++) {
  var file = files[i];

  var reader = new FileReader();

  reader.onload = ((file: any) => {
    return (e: Event) => {
      //use "e" or "file"
    }
  })(file);

  reader.readAsText(file);
}

答案 5 :(得分:-1)

由于变量文件在范围内,您可以使用文件变量而不将其传递给函数。

&#13;
&#13;
function openFiles(evt){
    var files = evt.target.files;
    for (var i = 0; i < files.length; i++) {
          var file=files[i];    
          reader = new FileReader();
          reader.onload = function(){
              alert(file.name);
              alert(this.result);
          };
      reader.readAsText(file);
    }
  }

files_input.addEventListener("change", openFiles, false);
&#13;
<input type="file" id="files_input" multiple/>
&#13;
&#13;
&#13;