UI から得たファイルを受け取るには FileReader() を使うらしいのですが、複数を処理するにはちょっとコツが必要なようです。
具体的には下のようなコードになります。
function getFiles(event) {
let work = []
let collection = event.dataTransfer.files
// or = event.target.files
let fr = new FileReader()
return new Promise(resolve => {
let i = 0
fn()
function fn() {
fr.readAsText(collection[i])
fr.onload = () => {
work[i] = fr.result
if (i < collection.length - 1) {
i++
fn()
}
else {
resolve(work)
}
}
}
})
}
event から file collection を受け取る
まずは受け取ります。画面上にドロップされたファイルは evetn.dataTransfer.files で、ファイル選択画面から入力されたファイルは event.target.files で受け取ります。
FileReader()
FileReader() をセットします。データの取り出しは繰り返し処理で何度も行いますが、 FileReader() は 1 回だけ使います。
再帰処理
ファイルの数だけ繰り返し処理です。 for 文を使うと FileReader() のデータ吸いだしが同時に発生して怒られるので再帰処理をします。再帰処理の部分だけ抜き出すと下のようになります。
return new Promise(resolve => {
let i = 0
fn()
function fn() {
// 処理
if (i < collection.length - 1) {
i++
fn()
}
else {
resolve(work)
}
}
})
readAsText()
テキストファイルを受け取るには readAsText() を使います。受け取るファイルに応じて適宜変更が必要です。
onload
データを読むのに時間がかかるみたいです。 onload のイベントが発生するのでこれを待って処理を行います。
result
読み込みが終わったら result で結果を受け取ります。
終わりに
FileReader() を 1 回だけ作るのではなく fr[i] = new FileReader() などしていれば再帰処理ではなくfor 文が使えたのかもしれないな、と今さら思っています。どうなんでしょうね。