HTML + JavaScriptでドラッグアンドドロップを実装してみた

概要

HTML + JavaScriptを用いてリストの順序をドラッグアンドドロップで変更できる方法について備忘録として自分なりに整理してまとめました。
今回はHTML ドラッグ & ドロップ APIを用いて実装しました。

HTML ドラッグ & ドロップ API - Web API | MDN
HTML ドラッグ & ドロップインターフェイスにより、アプリケーションはブラウザーでドラッグ & ドロップ機能を使用することができます。

このコードを書くことになった経緯は個人で利用している学習記録アプリでこの機能が欲しくなったからです。
以下がこの機能を使って解決したissueです。

カテゴリーの並び順を変更できるようにする · Issue #83 · nakajima97/laravel-study-record-app-v2
概要 カテゴリーの並び順を変更できるようにする ドラッグアンドドロップで順番を移動できるようにする タスク カテゴリーの並び順を変更できるようにする メモ HTMLドラッグ&ドロップAPIを用いて実装する

やってみた

以下サンプルコードです。

ポイントとしては挿入する位置を指定する以下のコードです。

// ドロップしたとき
const onDrop = (event) => {
    const items = [...document.querySelectorAll(".drag-target")];
    if (items.indexOf(event.currentTarget) === 0) {
        // リストの先頭に追加する
        event.currentTarget.before(
            document.getElementById(event.dataTransfer.getData("text"))
        );
    } else {
        // 対象の後ろに追加する
        event.currentTarget.after(
            document.getElementById(event.dataTransfer.getData("text"))
        );
    }
};

ドラッグ&ドロップで順番を変更するので直感的なほうが良いと思います。
個人的には今重ねている要素の後ろに追加される方が自然なので event.currentTraget.after が基本の動作にしております。
しかし、これではリストの先頭に入れることができないです。
なので、1つ目の要素の上でドロップした場合はドロップした場所の後ろではなく、先頭に追加するようにしました。

感想

JavaScriptは勉強不足なこともあり、こんな便利なAPIがデフォルトであることを初めて知りました。

正直dragoverでpreventDefaultが必要な理由がつかめていない。。。

target.addEventListener("dragover", (event) => {
  // ドロップできるように既定の動作を停止
  event.preventDefault();
});

MDNでも以下のように書かれているから書いているだけというのが正直なところです。

ドロップを許可したい場合は、 dragenter および dragover イベントの両方をキャンセルして、既定の処理を防ぐ必要があります。

https://developer.mozilla.org/ja/docs/Web/API/HTML_Drag_and_Drop_API/Drag_operations#%E3%83%89%E3%83%AD%E3%83%83%E3%83%97%E5%85%88%E3%81%AE%E6%8C%87%E5%AE%9A

なので、ドラッグ&ドロップ1つとってもまだまだ勉強することがあるなと。
今後も勉強がんばります!!

Follow me!

コメント

PAGE TOP
タイトルとURLをコピーしました