JavaScriptでドラッグ&ドロップでの画像アップロード機能を実装するのに便利な6つのイベント

ドラッグ&ドロップアップローダーを自作する

JavaScriptでは、ドラッグ&ドロップ関連の動作を検知するイベントが備わっているため、自作でドラッグ&ドロップアップロード機能を構築することができます。

イベント(ドラッグしている要素で発生)

イベント名発生条件
dragstart要素のドラッグを開始
dragドラッグ中
dragendドラッグを終了
ドラッグ&ドロップのイベント

イベント(ドラッグ要素を受け入れる要素で発生)

イベント名発生条件
dragenterドラッグ中でマウスポインターが要素上に乗った時
dragoverドラッグ中でマウスポインターが要素上に存在するとき
dragleaveドラッグ中でマウスポインターが要素上から離れた時
drop要素をドロップした時
ドラッグ&ドロップのイベント

プロパティ

プロパティ意味
event.dataTransfer.filesドロップされたファイルの情報オブジェクト(FileListオブジェクト)

サンプルコード

サンプルコードとして、画像をドラッグ&ドロップでアップロードして、その時の格納先であるevent.datatrasger.filesオブジェクトから情報を取得して画像を表示するスクリプトを紹介します。

Output
【画像アップロードエリア】
画像をドラッグ&ドロップで置いてください。
(サーバーには送られません。学習目的のスクリプトです。)
【画像のプレビューエリア】
Pug
div 【画像アップロードエリア】
		div#fileTarget.mt-3 画像をドラッグ&ドロップで置いてください。<br> (サーバーには送られません。学習目的のスクリプトです。)
		div.mt-4 【画像のプレビューエリア】
		div#imageList.w-100.mt-4
SCSS
#fileTarget {
	width: 100%;
  height: 150px;
	border: 2px solid #576574;
	text-align: center;
}
#imageList {
	text-align: center;
	img {
		width: 100%;
		max-width: 768px;
	}
}
JavaScript
// ファイルアップロードゾーン
const fileTarget = document.getElementById('fileTarget');

// ファイルアップロードゾーンに着脱するクラス
const className = 'on';

// ドラッグした要素が重なったときの処理
fileTarget.addEventListener('dragover', (event) => {
  // デフォルトの挙動を停止(画像をブラウザにアップロードした時に別タブで画像を表示する挙動の回避)
  event.preventDefault();
  fileTarget.classList.add(className);
});

// ドラッグした要素が離れたときの処理
fileTarget.addEventListener('dragleave', () => {
  // デフォルトの挙動を停止(画像をブラウザにアップロードした時に別タブで画像を表示する挙動の回避)
  event.preventDefault();
  fileTarget.classList.remove(className);
});

// ドロップした時の処理
fileTarget.addEventListener('drop', (event) => {
  // デフォルトの挙動を停止
  event.preventDefault();
  fileTarget.classList.remove(className);

  // Fileオブジェクトを参照
  const transferdFiles = event.dataTransfer.files;

  // 画像を表示する
  displayImages(transferdFiles);
});

/** 画像の表示処理 */
function displayImages(transferdFiles) {
  // 画像ファイルの格納配列
  const imageFileList = [];

  // ファイル数
  const fileNum = transferdFiles.length;

  // ファイルが画像のもののみを配列に格納する
  for (let i = 0; i < fileNum; i++) {
    if (transferdFiles[i].type.match('image.*') === false) {
      return;
    }
    imageFileList.push(transferdFiles[i]);
  }

  // 画像表示エリアの参照
  const imagePreviewArea = document.getElementById('imageList');

  // 各画像ファイルについて処理
  for (const imageFile of imageFileList) {
    // 画像ファイルの読み込み処理
    const fileReader = new FileReader();
    fileReader.readAsDataURL(imageFile);
    fileReader.addEventListener('load', (event) => {
      const image = new Image();
      image.src = event.target.result;
      // 表示エリアの先頭に画像ファイルを表示
      imagePreviewArea.insertBefore(image, imagePreviewArea.firstChild);
    });
  }
}
インストラクター
コメント

コメントを残す