ドラッグ&ドロップ

dragstart dragover drop DataTransfer

HTML Drag and Drop APIを使って要素のドラッグ&ドロップ操作を実装します。

デモ①:アイテムをドロップゾーンに移動

ドラッグ元:

🍎 りんご
🍌 バナナ
🍇 ぶどう
🍓 いちご
🥝 キウイ

ドロップ先:

ここにドロップ

デモ②:ドラッグで並び替え

🍎 りんご
🍌 バナナ
🍇 ぶどう
🍓 いちご
🥝 キウイ

コード例

js
// ドラッグ可能な要素
const draggable = document.querySelector('.item');
draggable.setAttribute('draggable', 'true');

draggable.addEventListener('dragstart', (e) => {
  e.dataTransfer.setData('text/plain', 'アイテムのID');
  e.dataTransfer.effectAllowed = 'move';
  draggable.classList.add('dragging');
});

draggable.addEventListener('dragend', () => {
  draggable.classList.remove('dragging');
});

// ドロップゾーン
const dropzone = document.querySelector('.dropzone');

dropzone.addEventListener('dragover', (e) => {
  e.preventDefault(); // これがないとdropが発火しない
  e.dataTransfer.dropEffect = 'move';
  dropzone.classList.add('drag-over');
});

dropzone.addEventListener('dragleave', (e) => {
  // relatedTarget でゾーン外への移動を判定
  if (!dropzone.contains(e.relatedTarget)) {
    dropzone.classList.remove('drag-over');
  }
});

dropzone.addEventListener('drop', (e) => {
  e.preventDefault();
  dropzone.classList.remove('drag-over');
  const data = e.dataTransfer.getData('text/plain');
  console.log('ドロップされたデータ:', data);

  // ファイルのドロップ
  const files = e.dataTransfer.files;
  for (const file of files) {
    console.log(file.name, file.size, file.type);
    const reader = new FileReader();
    reader.readAsDataURL(file);
    reader.onload = () => { img.src = reader.result; };
  }
});

NEWFile System Access API(ファイルのドロップ → 直接書き込み)

ドロップされたファイルをFileSystemFileHandleとして取得し、読み取り・書き込みができます(Chrome 86+)。

js
// ドロップイベントでFileSystemFileHandleを取得
dropzone.addEventListener('drop', async (e) => {
  e.preventDefault();
  for (const item of e.dataTransfer.items) {
    if (item.kind === 'file') {
      // ✅ FileSystemFileHandle として取得
      const handle = await item.getAsFileSystemHandle();
      if (handle.kind === 'file') {
        const file = await handle.getFile();
        const content = await file.text();

        // ファイルに書き込み(ユーザー許可後)
        const writable = await handle.createWritable();
        await writable.write('新しいコンテンツ');
        await writable.close();
      }
    }
  }
});

// ファイルピッカー
const [fileHandle] = await window.showOpenFilePicker();
const file = await fileHandle.getFile();

// フォルダピッカー
const dirHandle = await window.showDirectoryPicker();

🤖 AIプロンプトテンプレート

以下の要件を満たすTypeScript + Reactコンポーネントを作成してください。

- HTML5 Drag and Drop APIを使ったドラッグ&ドロップのサンプルを示す
- dragstart/dragover/drop/dragendイベントの処理例を含める
- DataTransferオブジェクトを使ったデータの受け渡しのサンプルを含める
- ファイルをドロップしてアップロードするUIの例を示す
- ドラッグ中のビジュアルフィードバック(ドロップゾーンのハイライト)のサンプルを含める
- コメントは日本語で記述する

⚠️ このプロンプトはあくまでたたき台です。AIの回答はモデルやバージョン、会話の文脈によって毎回異なります。意図通りに動かない場合は、条件を追記・修正してお使いください。