0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

HTML DnDについて

Posted at

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()はブラウザによって挙動差がある

参考元

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?