web-dev-qa-db-ja.com

結果とパラメーターを含む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);

onload関数でfilereader.resultを使用します。この関数にファイルなどのパラメーターを使用すると、結果にアクセスできなくなります。たとえば、onload関数でfile.nameを使用したいと思います。この問題を解決するには?

20
PatriceG

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);
    }
}

ここで閉鎖が必要な理由については、これらの関連する質問を参照してください。

43
Chris

「onload」ハンドラでクロージャを使用する必要があります。例: 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);
6
sergolius

イベント処理は非同期であるため、すべての囲まれたローカル変数の最新の値を取得します(クロージャー)。特定のローカル変数をイベントにバインドするには、上記のユーザーから提案されたコードに従うか、この実例を見ることができます:

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
sahilbathla

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);
}
0