【PR】を含みます。

フロントエンド

【JavaScript】ドラッグ&ドロップによるファイルアップロード機能を実装する方法と注意点

JavaScript ドラッグ&ドロップによるファイルアップロード機能を実装する方法と注意点

Webサイトでのファイルアップロード機能は、ユーザーにとって非常に重要な要素です。

中でも、ドラッグ&ドロップによるファイルアップロードは直感的な操作が可能なため、ユーザビリティの向上につながります。

この記事では、JavaScriptを使ってドラッグ&ドロップでファイルをアップロードする機能を実装する方法と、開発時に気をつけたい注意点を解説します。

ドラッグ&ドロップで要素を移動する方法は以下の記事で紹介しています。

あわせて読む
JavaScript ドラッグ&ドロップで要素を移動する方法とサンプルコード
【JavaScript】ドラッグ&ドロップで要素を移動する方法とサンプルコード

もくじ【サンプル】ドラッグ&ドロップで特定のエリア内で要素を自由に動かす【実装コード】ドラッグ&ドロップで特定のエリア内で要素を自由に動かす【サンプル】ドラッグ&ドロップでリスト要素を並び替える【実装 ...

【サンプル】ドラッグ&ドロップによるファイルアップロード機能

ここにファイルをドラッグ&ドロップ
または

選択されたファイル:

【実装コード】ドラッグ&ドロップによるファイルアップロード機能

Copyをクリックするとコピーできます。

HTML
Copy
  <div class="file-upload-container">
    <div id="drop-area" class="drop-area">
      <p class="drop-message">ここにファイルをドラッグ&ドロップ<br>または</p>
      <label for="file-input" class="visually-hidden">ファイルを選択してください</label>
      <input type="file" id="file-input" class="file-input" multiple>
      <button id="select-file-btn" class="select-file-btn">ファイルを選択する</button>
      <button id="change-file-btn" class="change-file-btn">ファイルを変更する</button>
    </div>
    <p class="file-upload-text">選択されたファイル:</p>
    <div id="file-list" class="file-list"></div>
  </div>
CSS
Copy
.drop-area {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  min-height: 200px;
  margin-bottom: 1em;
  padding: 1em;
  text-align: center;
  border: dashed 2px #ccc;
  border-radius: 5px;
}
.drop-area.is-dragover {
  background: #f0f0f0;
  border-color: #666;
}
.drop-message {
  margin-bottom: 0.5em;
}
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  border: 0;
}
.file-input {
  display: none;
}
.select-file-btn,
.change-file-btn {
  padding: 0.5em 1em;
  color: #fff;
  background: #3c3c3c;
  border: none;
  border-radius: 5px;
  transition: 0.3s;
  cursor: pointer;
}
.select-file-btn:hover,
.change-file-btn:hover {
  opacity: 0.8;
}
.change-file-btn {
  display: none;
}
.file-upload-text {
  margin: 0 0 0.5em;
}
.file-list p {
  margin: 0 0 0.5em;
}
.file-list p:last-child {
  margin-bottom: 0;
}
JavaScript
Copy
const dropArea = document.getElementById('drop-area');
const fileInput = document.getElementById('file-input');
const selectFileBtn = document.getElementById('select-file-btn');
const changeFileBtn = document.getElementById('change-file-btn');
const fileList = document.getElementById('file-list');
let selectedFiles = [];
// ドラッグ&ドロップイベント
dropArea.addEventListener('dragover', (e) => {
  e.preventDefault();
  dropArea.classList.add('is-dragover');
});
dropArea.addEventListener('dragleave', () => {
  dropArea.classList.remove('is-dragover');
});
dropArea.addEventListener('drop', (e) => {
  e.preventDefault();
  dropArea.classList.remove('is-dragover');
  selectedFiles = Array.from(e.dataTransfer.files);
  displayFileList(selectedFiles);
});
// ボタンによるファイル選択
selectFileBtn.addEventListener('click', () => {
  fileInput.click();
});
changeFileBtn.addEventListener('click', () => {
  fileInput.click();
});
// input経由でファイルが選択されたとき
fileInput.addEventListener('change', () => {
  selectedFiles = Array.from(fileInput.files);
  displayFileList(selectedFiles);
});
// ファイルリストを表示する
function displayFileList(files) {
  fileList.innerHTML = '';
  files.forEach((file) => {
    const item = document.createElement('p');
    item.textContent = file.name;
    fileList.appendChild(item);
  });
  // ボタンの切り替え処理
  if (files.length > 0) {
    selectFileBtn.style.display = 'none';
    changeFileBtn.style.display = 'inline-block';
  } else {
    selectFileBtn.style.display = 'inline-block';
    changeFileBtn.style.display = 'none';
  }
}

サーバーへのアップロード処理(擬似)

バックエンドの実装は割愛しますが、以下はフロントエンド側での処理の例です。

「アップロードする」ボタンを設置して、アップロードされたファイルをサーバー側に転送しています。

Copyをクリックするとコピーできます。

HTML
Copy
<button id="upload-btn" class="upload-btn">アップロードする</button>
JavaScript
Copy
const uploadBtn = document.getElementById('upload-btn');
// アップロード処理(擬似)
uploadBtn.addEventListener('click', () => {
  if (selectedFiles.length === 0) {
    alert('ファイルを選択してください');
    return;
  }
  const formData = new FormData();
  selectedFiles.forEach((file) => {
    formData.append('files[]', file);
  })
  fetch('/upload.php', {
    method: 'POST',
    body: formData
  })
    .then((response) => {
      if (!response.ok) {
        throw new Error(`HTTPエラー: ${response.status}`);
      }
      return response.text();
    })
    .then((data) => {
      console.log(data);
      alert('アップロード成功しました');
    })
    .catch((error) => {
      console.error('アップロード失敗:', error);
      alert('アップロードに失敗しました');
    });
});

よくあるエラーと対処法

エラー内容 対処法
ドラッグしても反応しない preventDefault()を忘れていないか確認
CORSエラー サーバー側のCORS設定を確認

実装時の注意点とセキュリティ

複数ファイルの対応 multiple属性が必要
拡張子チェック JS側・サーバー側でMIMEタイプのバリデーションを行う
サーバー側の対策 ファイル名のサニタイズ、保存先制限、ウイルスチェックなどを行う

まとめ

ドラッグ&ドロップによるファイルアップロードは、JavaScriptを使えば比較的簡単に実装できます。

ユーザーの利便性を高めるためにも、積極的に取り入れてみましょう。

ただし、セキュリティやユーザー体験に関する配慮は不可欠です。

今回紹介した注意点も参考に、安全で使いやすいファイルアップロード機能を実現してください。

ドラッグ&ドロップで要素を移動する方法は以下の記事で紹介しています。

あわせて読む
JavaScript ドラッグ&ドロップで要素を移動する方法とサンプルコード
【JavaScript】ドラッグ&ドロップで要素を移動する方法とサンプルコード

もくじ【サンプル】ドラッグ&ドロップで特定のエリア内で要素を自由に動かす【実装コード】ドラッグ&ドロップで特定のエリア内で要素を自由に動かす【サンプル】ドラッグ&ドロップでリスト要素を並び替える【実装 ...

-フロントエンド
-