君は心理学者なのか?

大学時代に心理学を専攻しなぜかプログラマになった、サイコ(心理学)プログラマかろてんの雑記。

【JavaScript】画像をdrag and dropしてサムネイルを表示する〜DragEvent, DataTransfer, File, FileReaderオブジェクトについて〜

こういうのがやりたかった

f:id:karoten512:20180223161259g:plain

手順

簡単に言うと、

  • DragEventからDataTransferを取得

  • DataTransferからFileを取得

  • FileをFileReaderで読み込み、サムネイルとして表示

という手順になります。

1. dropエリアの準備

1-1. まずはdropエリアを作成する

imgは後でサムネイルを表示する際に使います。

<div id='droparea'>
</div>
<img src='' id='thumb'>
#droparea {
  width: 200px;
  height: 100px;
  border: 3px dotted #ccc;
}

1-2. dropエリアにイベントリスナを登録

const droparea = document.getElementById('droparea');
droparea.addEventListener('drop', function(evt) {
  console.log('dropしたよ');
  /** 以下、drop後の処理 */
}, true);

この中にdrop後の処理を書き込んでいきます。

2. dragしたファイル(Fileオブジェクト)を受け取る

dropしたファイルを取得します。

まず、dropイベントの中身を見てみましょう。

console.log(evt);

f:id:karoten512:20180223153824p:plain

DragEventというオブジェクトのようです。

今回用があるのは、このオブジェクトが持つ

DataTransferというオブジェクトです。

console.log(evt.dataTransfer);

f:id:karoten512:20180223154003p:plain

DataTransferオブジェクトがもつfilesというプロパティから、

ドラッグされたFileオブジェクトにアクセスすることが出来ます。

/** 全件取得 */
console.log(evt.dataTransfer.files);
/** 1件取得 */
console.log(evt.dataTransfer.files[0]);

f:id:karoten512:20180223153619p:plain

複数件まとめて扱うこともできそうですね。

3. 取得したFileオブジェクトを、FileReaderで読み込む

ソースコード

droparea.addEventListener('drop', function(evt) {
  // ファイルオブジェクトの取得
  const file = evt.dataTransfer.files[0];
  
  // FileReaderの生成
  const reader = new FileReader();
  
  reader.onload = function() {
    // ファイルを読み込んだ後の処理
    console.log(reader.result);

    // サムネイルとして表示
    const thumb = document.getElementById('thumb');
    thumb.src = reader.result;
  };

  // ファイルの読み込み
  reader.readAsDataURL(file);
 
  // ブラウザのデフォルト挙動を抑制
  evt.preventDefault();

}, true);

FileReaderの解説

html5から、

FileReaderというローカルファイルを読み込めるAPIが使えるようになりました。

FileReaderが扱えるのはFileオブジェクト(またはBlobオブジェクト)です。

reader.onload = function() {
  // ファイルを読み込んだ後の処理
  // reader.resultでファイル内容にアクセスできる
};

としてファイルを読み込んだ後の処理を記載します。

読み込んだ結果は、

reader.resultでアクセスできます。

reader.readAsDataURL(file);

としてファイルオブジェクトを読み込みます。

完成したソースコード

const droparea = document.getElementById('droparea');

// dropイベントのリスナーを設定
droparea.addEventListener('drop', function(evt) {

  // Fileオブジェクトの取得
  const file = evt.dataTransfer.files[0];
  
  // FileReader生成
  const reader = new FileReader();
  
  // ファイルを読み込んだ後の処理
  reader.onload = function() {
      // サムネイルとして表示
      const thumb = document.getElementById('thumb');
      thumb.src = reader.result;
  };

  // ファイルの読み込み
  reader.readAsDataURL(file);

  evt.preventDefault();

}, true);