🌊

Drag & Drop APIのイベントの整理

2024/09/21に公開

業務の中で、ドラッグ&ドロップを実装する機会があり、
イベントの種類がそこそこあったので、知識を整理しておきます。

この記事では、HTMLのDrag & Drop APIの定義を整理した上で、
最後に実際に動かして理解できるコードを書くという流れにします。

Drag & Drop APIの各種イベント

主要なイベントについて整理します。
以下の表のようになります。

イベント 定義 備考
drag ドラッグ対象の要素がドラッグされている間に発生し続ける 数百ミリ秒間隔で発生するので、常に発生している感覚
dragstart ドラッグ対象の要素をdragし始めた段階で発生
dragend ドラッグの終了時に発生 成功したか中断したかに関係なく発生(ドラッグ対象の要素をドロップしたり、escを押した時に発生)
dragenter ドラッグしている要素がドロップ可能な要素に入った時に発生
dragleave ドラッグしている要素がドロップ可能な要素を出た時に発生
dragover ドラッグしている要素がドロップ可能な要素の上にあるが、ドロップしていない間に発生し続ける 数百ミリ秒間隔で発生するので、常に発生している感覚
drop ドラッグしている要素がドロップされた時に発生

実際に動かしながら確認してみる

PlayCodeで動作確認しやすいよう、
ディレクトリ構成やファイル名をPlayCodeに合わせておきます。
JavaScriptのテンプレートで動作確認しました。
画面の下半分に、Console並びにWebViewが以下のように表示されて動作確認できます。

下記のコードをコピペするだけで動作確認できますので、ご興味あればぜひやってみてください。

index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>ドラッグ&ドロップの検証</title>
    <link rel="stylesheet" href="src/style.css">
</head>
<body>
    <div id="draggable" draggable="true">これをドラッグ</div>
    <div id="dropzone">ここにドロップ</div>

    <script src="src/script.js"></script>
</body>
</html>

src/style.css
#draggable {
    width: 150px;
    height: 100px;
    background-color: lightblue;
    margin: 10px;
    cursor: move;
}

#dropzone {
    width: 200px;
    height: 200px;
    background-color: lightgray;
    margin: 10px;
    border: 2px dashed #333;
}

src/script.js
const draggable = document.getElementById('draggable');
const dropzone = document.getElementById('dropzone');

draggable.addEventListener('dragstart', (event) => {
    console.log('dragstart');
});

draggable.addEventListener('drag', (event) => {
    // 発生しまくって他のイベントが確認しにくいので、
    // 他のイベントを確認するときはコメントアウト推奨
    // console.log('drag');
});

draggable.addEventListener('dragend', (event) => {
    console.log('dragend');
});

dropzone.addEventListener('dragenter', (event) => {
    console.log('dragenter');
});

dropzone.addEventListener('dragleave', (event) => {
    console.log('dragleave');
});

dropzone.addEventListener('dragover', (event) => {
    // ドロップイベントの発生を拒否するデフォルトの挙動を無効にする
    event.preventDefault();  
    // 発生しまくって他のイベントが確認しにくいので、
    // 他のイベントを確認するときはコメントアウト推奨
    // console.log('dragover');
});

dropzone.addEventListener('drop', (event) => {
    console.log('drop');
});

Discussion