UGA Boxxx

つぶやきの延長のつもりで、知ったこと思ったこと書いてます

【DND】Drag and Drop の Propagation(伝播)について

Drag and Drop における Propagation(伝播)について調べた

Propagationとは、ドラッグ操作中に発生するイベントがDOMツリー内でどのように伝わるかに関連する概念

ポイントをまとめると以下

1. Drag and Dropの基本的な流れ

HTML5のDrag and Drop APIを使うと、以下のイベントが主に関与する

  • dragstart
  • drag
  • dragenter
  • dragover
  • dragleave
  • drop
  • dragend

2. イベントの伝播

イベント伝播は一般的なDOMイベントの伝播ルールに従う

  • キャプチャリングフェーズ:親要素から子要素へイベントが伝播
  • ターゲットフェーズ:イベントが発生した要素で処理
  • バブリングフェーズ:子要素から親要素へイベントが戻る

3. Drag and Drop固有の考慮点

Drag and Dropでは以下の伝播が問題になる場合が多い

  • バブリング(Bubbling)
    たとえば、dragoverイベントがネストした要素にある場合、子要素で発生したイベントが親要素にも伝わる。このため、意図しない挙動が発生する可能性がある

  • デフォルトのキャンセル

    • dragoverdropでは、ブラウザのデフォルト動作をキャンセルする必要がある。これをしないと、例えばドロップエリアでのファイルアップロードが機能しない
    • event.preventDefault()を使う
  • stopPropagationの使用

    • 必要に応じてevent.stopPropagation()を使い、イベントの伝播を止めることで特定の要素だけでイベントを処理する

developer.mozilla.org

4. 実践例

以下はドラッグ操作が親要素と子要素で干渉しないように制御する例

function handleDragOverParent(event) {
  event.preventDefault();
  console.log('Parent dragover');
}

function handleDragOverChild(event) {
  event.preventDefault();
  event.stopPropagation(); // 子要素でイベントの伝播を停止
  console.log('Child dragover');
}

document.getElementById('parent').addEventListener('dragover', handleDragOverParent);
document.getElementById('child').addEventListener('dragover', handleDragOverChild);
<div id="parent" style="width: 300px; height: 300px; background: lightblue;">
  Parent
  <div id="child" style="width: 150px; height: 150px; background: coral;">
    Child
  </div>
</div>