HTML ドラッグ&ドロップとは
HTML ドラッグ & ドロップインターフェイスにより、ブラウザーでドラッグ & ドロップ機能を使用することができる。
ユーザーはマウスでドラッグ可能な要素を選択し、その要素をドロップ可能な要素へドラッグし、マウスボタンを離すことでドロップすることができる。ドラッグ操作の間、ドラッグ可能な要素の半透明の表示がマウスポインターに続く。
ドラッグ可能にできる要素の種類、ドラッグ可能な要素が生成するフィードバックの種類、およびドロップ可能な要素はカスタマイズ可能。
ドラッグイベント
HTML ドラッグ & ドロップ ではDOMイベントモデルとマウスイベントを継承したドラッグイベントを使用する。
| イベント名 | 発火タイミング |
|---|---|
| dragstart | ドラッグの開始時(要素をつかんだ瞬間) |
| drag | ドラッグ中(高頻度で発火) |
| dragend | ドラッグ終了時(ドロップ完了やキャンセル) |
| dragenter | ドロップ対象に入ったとき |
| dragover | ドロップ対象の上にある間(e.preventDefault()が必要) |
| dragleave | ドロップ対象から外れたとき |
| drop | ドロップが完了したとき |
インターフェース
| インターフェース | 説明 |
|---|---|
DragEvent |
DnD関連のイベントオブジェクト。dataTransferを持つ。 |
DataTransfer |
ドラッグ中にデータをやり取りするためのオブジェクト。 |
DataTransferItem |
個々のデータアイテムを表す。 |
DataTransferItemList |
データアイテムのリストを管理。 |
実装例
ドラッグ可能なものを特定
HTML要素に draggable="true" 属性をつけることでドラッグ可能になる。
<div id="drag-item" draggable="true" class="box">Drag me</div>
ドラッグするデータの定義
dragstart イベントで dataTransfer.setData() を使ってデータを設定する。
const dragItem = document.getElementById("drag-item");
dragItem.addEventListener("dragstart", (e) => {
e.dataTransfer.setData("text/plain", dragItem.id);
});
ドラッグ画像の定義
デフォルトでは要素の半透明コピーがドラッグ画像になるが、setDragImage()で独自画像を指定できる。
dragItem.addEventListener("dragstart", (e) => {
const ghost = document.createElement("div");
ghost.textContent = "Dragging!";
ghost.style.padding = "8px";
ghost.style.background = "#333";
ghost.style.color = "#fff";
document.body.appendChild(ghost);
e.dataTransfer.setDragImage(ghost, 0, 0);
});
ドラッグ&ドロップ効果の定義
effectAllowed と dropEffect を使うと、カーソルや操作意図を制御できる。
e.dataTransfer.effectAllowed = "move"; // copy, link, move など
ドロップゾーンの定義
ドロップ先要素で dragover と drop を処理する。
dragoverで e.preventDefault() を呼ばないと、drop イベントは発火しない。
<div id="drop-zone" class="box"></div>
const dropZone = document.getElementById("drop-zone");
dropZone.addEventListener("dragover", (e) => e.preventDefault());
dropZone.addEventListener("drop", (e) => {
e.preventDefault();
const data = e.dataTransfer.getData("text/plain");
dropZone.textContent = `Dropped: ${data}`;
});
ドラッグの終了
dragend イベントで後処理を行う。
dragItem.addEventListener("dragend", () => {
dragItem.style.opacity = "1";
});
応用例
リスト並び替え
See the Pen リスト並び替え by 内山綾斗 (@xqdgoyea-the-vuer) on CodePen.
ファイルドロップアップロード
See the Pen Untitled by 内山綾斗 (@xqdgoyea-the-vuer) on CodePen.
キャンバスや地図上での要素配置
See the Pen Untitled by 内山綾斗 (@xqdgoyea-the-vuer) on CodePen.
注意点
- dragoverでevent.preventDefault()を定義しないとdropイベントは発火しない
- HTML DnD API はモバイルブラウザでのサポートが限定的な可能性がある
- setDragImage()はブラウザによって挙動差がある
参考元