本記事では、ドラッグ&ドロップで複数のアイテムの順番を入れ替える実装方法を解説します。
実装例)To Do リストの順番を入れ替える
- Task 1
- Task 2
- Task 3
- Task 4
目次
HTML / CSS / JavaScript コード
<div class="container">
<ul id="todo-list">
<li draggable="true" class="draggable">Task 1</li>
<li draggable="true" class="draggable">Task 2</li>
<li draggable="true" class="draggable">Task 3</li>
<li draggable="true" class="draggable">Task 4</li>
</ul>
</div>実装のポイント
ドラッグ&ドロップの基礎については以下記事でも解説していますが、改めて本記事でもポイントを解説します。
あわせて読みたい


【JS】ドラッグ&ドロップの実装方法
本記事では、以下のように直感的にアイテムを操作できるドラッグ&ドロップの基本的な実装方法について紹介します。 こちらのブロックをドラッグできます。 ドラッグし…
HTML構造:特定の要素をドラッグできるようにする
draggable="true"属性を設定することで、設定された要素がドラッグできるようになります。
今回の実装例ではタスク全てを個別にドラッグさせたいので、タスクの構成要素である<li>タグすべてにdraggable="true"を設定しています。
CSSスタイル:タスクの入れ替えができそうなスタイルを適用する
cursor: move;を設定することで、カーソルが十字の矢印に変化します。
JavaScriptイベント:ドラッグ&ドロップに関する各種イベントを設定する。
const listItems = document.querySelectorAll('#todo-list li');
listItems.forEach(item => {
// ---略---
});ドラッグ&ドロップを設定したい全タスクに対し、以下のイベントを設定します。
dragstartイベント-
ドラッグが開始されたときに発生します。
item.addEventListener('dragstart', (e) => { draggingItem = item; item.classList.add('dragging'); });ドラッグしているタスクを
draggingItemに代入し、ドラッグ中のアイテムにはdraggingクラス(CSSプロパティでグレーアウトさせる)を追加します。 dragendイベント-
ドラッグ操作が終了したときに発生します。
item.addEventListener('dragend', () => { draggingItem.classList.remove('dragging'); draggingItem = null; });dragstartイベントとは逆の操作を行います。
ドラッグ中のアイテムからdraggingクラスを削除し、draggingItem変数の中身をnullに戻します。 dragoverイベント-
ドラッグ中のタスクが他のタスク上にあるときに発生します。
item.addEventListener('dragover', (e) => { e.preventDefault(); const targetItem = e.target; if (targetItem !== draggingItem) { const bounding = targetItem.getBoundingClientRect(); const offset = bounding.y + bounding.height / 2; const list = document.getElementById('todo-list'); if (e.clientY - offset > 0) { list.insertBefore(draggingItem, targetItem.nextSibling); } else { list.insertBefore(draggingItem, targetItem); } } });- まず
e.preventDefault();でデフォルトの動作をキャンセルします。(これを行わないとタスクがドロップできません。) const targetItem = e.target;でホバーされているタスクの情報を取得し、tagetItem変数に代入します。if (targetItem !== draggingItem) {…}:ドラッグ中のタスクが他のタスク上にあるとき(自身のタスクでないとき)にのみ、以下の操作を行います。const bounding = targetItem.getBoundingClientRect();:ホバーされているタスクの位置とサイズの情報を取得します。const offset = bounding.y + bounding.height / 2;:ホバーされているタスクの縦方向の中心位置を計算します。if (e.clientY - offset > 0) {...}:ドラッグ中のタスクの縦方向の位置がホバーされているタスクの中心よりも下にある場合、以下の操作を行います。list.insertBefore(draggingItem, targetItem.nextSibling);:ドラッグ中のタスクをホバーされているタスクの次(下)に挿入します。
else {...}:それ以外の場合は、以下の操作を行います。list.insertBefore(draggingItem, targetItem);:ドラッグ中のタスクをホバーされているタスクの前に挿入します。
- まず
【応用】タスクを追加して保存もできるToDoリスト
タスクを自由に追加でき、さらにブラウザを閉じても内容が保存されるToDoリストを作成しました。
あわせて読みたい


メモ書きにも使えるToDoリストとその作り方
Add Clear 使い方 入力フォームに To Do を入力して「Add」ボタンをクリックすると、To Do が追加される。複数追加も可能。 各To Doはドラッグ&ドロップで順番を入れ替…
実装コードも公開しているので、よろしければ参考にしてみてください。
当サイトで公開しているWebデザインやUIの実装例は、一覧として以下記事に纏めています。
あわせて読みたい


Webデザイン・UIコンポーネント集(HTML/CSS/JS)
Webサイトやアプリで使われている『Webデザイン』や『UI』の実装例やデザイン例を纏めました。(随時更新中)実装方法などは別記事にコードや実装ポイントを公開してい…
