定義
「この項目をつまんであちらへ引っ張って置く」を作りたいが、その対象が互いに異なるリスト・領域(React コンポーネントの境界を越えて)にまたがるとき、この API を使う。ブラウザが直接ドラッグを管理してくれるので、境界を越える移動が簡単になる。
HTML5 Drag and Drop はブラウザが提供するネイティブなドラッグセッション(オペレーティングシステムが直接管理する本物のドラッグ状態)API だ。dragstart → dragover → drop / dragend イベントと DataTransfer(ドラッグしている間、移すデータを入れておくブラウザ内蔵の箱)でペイロード(移そうとする実際のデータ)を移し、ポインタが OS ドラッグループに入ってからでないと動かない。フレームワークが合成した(コードで真似た)マウスイベントだけでは、セッションが始まらない場合が多い。
なぜ必要か
エディター・リスト・ファイルアップロードで「選択領域を別の場所へ移す」という UX はよくある。React やインラインエディターが一つのサブツリーだけを所有するとき、フレームワーク内部の DnD では境界を越えられない。HTML5 DnD は DOM ツリー全体で動作するので、フォーカスされたサブツリーの外のターゲットへテキスト・ノードを移すチャネルになる。
動作原理
- ユーザーが選択領域をドラッグすると
dragstartが発生し、ハンドラがdataTransferにtext/plainなどの MIME タイプ(データ形式を表す名札。例: プレーンテキスト/HTML)ペイロードを入れる。 - ポインタが移動する間
dragoverが繰り返される。ドロップを許可するには、ターゲットでpreventDefault()が必要。 dropでペイロードを読み、caretRangeFromPoint(画面座標を受け取り、その地点のテキストカーソル位置を返すブラウザ関数)などで挿入位置を計算した後、ドメイン状態に反映する。dragendでセッションが終わる。img/aは既定でdraggableなので、意図しないネイティブドラッグを誘発しうる。
| 項目 | 説明 | 注意点 |
|---|---|---|
dragstart | セッション開始、ペイロード設定 | テキストドラッグは selection が必要 |
dragover | ドロップ許可のため preventDefault() | しないと drop が発生しない |
drop | ターゲットでペイロード受信 | 挿入位置の計算が肝 |
DataTransfer | MIME 別ペイロード | ブラウザごとにシリアライズの差 |
draggable | ドラッグソースを明示 | 装飾要素は false に |
実務での適用
クロスサブツリーの移動が必要なら、フレームワーク DnD の代わりに HTML5 チャネルを使い、ドロップ結果は**ドメインパッチ(原子的配置)**として反映する。ドラッグ開始時にフォーカス/エディターセッションを整理し、source of truth の race を除く。
E2E は OS ドラッグループを仮定せず、アプリが聞く DragEvent を合成ディスパッチして経路を検証する。Playwright の合成マウスは OS ループに入れず dragstart が出ない場合が多い。
トレードオフ
- ネイティブ API はクロスサブツリー・ファイルドロップに強いが、ブラウザごとの
DataTransfer・カーソル・アクセシビリティの差がある。 - ドラッグ中に React 再レンダーがソース/ターゲットの DOM を入れ替えるとセッションが切れる。ドラッグ中は再レンダーを最小化するか、静的レンダーに固定する必要がある。
使ってはいけない場合
- 同じサブツリー内の単純な並べ替えだけが必要で、ポインタイベント + 状態更新で十分な場合。
- タッチ専用の UX が本体の場合 — HTML5 DnD のタッチ対応は環境によって限定的だ。Pointer Events(マウス・タッチ・ペンを一つで扱う低レベル入力イベント)ベースの代替を検討する。
よくある間違い
dragoverでpreventDefault()を外し、dropが永遠に来ない。- 画像・リンク・ハンドルグリフがテキストドラッグを横取りする(
draggable={false}/ pseudo-element 未適用)。 - E2E が OS ドラッグを仮定し、CI でだけ失敗する。
- ドロップ座標が contenteditable と静的レンダーのどちらを指しているか区別しない。
関連概念
- selection-tostring-and-pseudo-content — ハンドルグリフが選択/コピーに混ざる問題と一緒に扱う場合が多い。
- focused-guest-editor — guest が一つのブロックだけを所有するとき、クロスブロック移動チャネルとして HTML5 DnD がよく選ばれる。