ファイルリーダーの結果と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
を使用したいと思います。この問題を解決するには?
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);
}
}
ここで閉鎖が必要な理由については、これらの関連する質問を参照してください。
「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);
イベント処理は非同期であるため、すべての囲まれたローカル変数の最新の値を取得します(クロージャー)。特定のローカル変数をイベントにバインドするには、上記のユーザーから提案されたコードに従うか、この実例を見ることができます:
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);
});
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);
}