ドラッグ&ドロップでファイルを一括取得したい(react)

タイトルの通りです。

ブラウザにドロップしたディレクトリ内のファイルを一括取得したいと思ったので、その方法を自分なりに調べてみました。

個人的になかなか難しかったので、忘れないようにブログという形で残すことにしました。

はじめに

まずは、この記事の中で目指す目標を紹介します。

目標

  • ディレクトリ丸ごと画面にドロップ!中のファイルを全て取得したい
  • サブディレクトリの中のファイルまで取得できれば完璧
  • できればパスも知りたい

なかなかの欲張りセットです。今回の記事では javaScript を用いてこれらの機能を実装していきます。ライブラリとして react.js を利用しますが、上記機能の実装に影響することはほとんどありません。ドラッグ&ドロップの実装が個人的に簡単になるくらいのイメージです。

既に react 以外でドラッグ&ドロップを実装できる方は、以下の手順1をスキップしても良いかもしれません。

手順

  1. ディレクトリ(or ファイル)をドロップできる環境を作る
  2. ファイル単体をドロップ、File オブジェクトを取得してみる
  3. ディレクトリをドロップ、全てのファイルを取得してみる

私の環境

  • OS:windows 10
  • editor:vscode
  • react関係
    • Node:v14.16.1 
    • npm:6.13.4
    • 「create-react-app」でファイル自動生成

実装

1.ディレクトリ(or ファイル)をドロップできる環境を作る

こちら、ドラッグ&ドロップに問題なしの方は読み飛ばして貰って構いません。ライブラリとして React.js を利用しています。

適当に枠を作る

新しくコンポーネントを作ります。コンポーネント名は「DropDirectory」にしておきます。

DropDirectry コンポーネントを表示

DropArea コンポーネントを作成、上記の枠を囲む

新しく「DropArea コンポーネント」を作成します。機能はシンプルです。ブラウザにディレクトリ(or ファイル)をドロップした際に動く既定の処理を停止させ、任意の関数を実行できるようにします。

引数「children」にはDropArea コンポーネントが囲った子コンポーネントが入ります。

以上です。これでディレクトリやファイルをドラッグ&ドロップする準備が整いました。次からは実際にファイルを取得してみようと思います。

2.ファイル単体をドロップ、ファイルオブジェクトを取得してみる

ファイルをドロップした際に呼ばれるコールバック関数を記述しましょう。

手順1で作成したコードでいうと、DropDirectory コンポーネントの「handleDrop」がこれに当たります。

以下の流れでファイルを取得できます。

コールバック関数

動作確認

テキストファイルをドロップしてみる

いざ、ドロップ!

表示されたログ。 ファイルが取得できている。

 

※1.e.dataTransfer.items[0]:複数ディレクトリ(or ファイル)をドロップした際、その先頭のディレクトリ(or ファイル)のみ取得する。この時点ではまだ File オブジェクトではなく、「DataTransferItem オブジェクト」として扱われる。

※2.webkitGetAsEntry():DataTransferItem オブジェクトを「FileSystemFileEntry オブジェクト」もしくは「FileSystemDirectoryEntry オブジェクト」に変換する。変換された 後は、上記コードのように「isFile」「isDerectory」によってどちらのEntry かを判別することができる。

※3:FileSystemFileEntry オブジェクトから File オブジェクトを取得する。非同期での動作なので、処理が完了した後でログを表示させている。

3.ディレクトリをドロップ、全てのファイルを取得してみる

ディレクトリの中には、ファイルとサブディレクトリがあります。

サブディレクトリの中にも、ファイルとサブディレクトリがあります。

よって、ディレクトリがドロップされた際には、ファイルとディレクトリを識別するスキャン関数を再帰的に呼び出す必要があります。コールバック関数を次のように変更します。

コールバック関数

動作確認

ドロップ用テストディレクトリ。12のテキストファイルが仕込まれている。

 

サブディレクトリ以下のファイルも含めて合計12個、見事に取得できた。

まとめ

一応これで、今回の目標は達成できたと思います。しかし、せっかく読み込んだファイルの使い道がログへの表示だけというのも、ちょっと味気ないですよね。オーディオファイルを再生してみたり、画像ファイルを表示してみたり、どうぞ好きなように使ってみてください。

まだまだ説明不足な点もあるかもしれませんが、この記事が誰かの役に立てれば幸いです。

  • このエントリーをはてなブックマークに追加