0Pricing
HTML Academy · レッスン

実践:ドラッグで並べ替えるリスト

Drag and Drop APIで並べ替え可能なリストを作成します

「実践:ドラッグで並べ替えるリスト」はCoddyKit上の無料HTML Academyレッスンです。 これはレッスン4/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはHTML Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 HTML Academyコースには全4レッスンが含まれています。

パターン概要

ドラッグして並べ替えるリストを作るには、すべての項目をドラッグ可能にし、dragstartでドラッグ中の項目のidをdataTransferに保存します。そしてdropで、ドラッグした要素を対象の前または後ろに挿入します。各ドロップの後にDOMから順序を再構築すれば、DOMとモデルの状態を同期できます。

マークアップ

すべてのliにdraggable="true"とdata-idを持たせたフラットなリストをレンダリングします。要素にidを保持しておけば、ドラッグハンドラーは項目を特定するために別の状態ストアを検索する必要がありません。要素自体が信頼できる情報源になります。

<ul id="list">
  <li draggable="true" data-id="1">Item 1</li>
  <li draggable="true" data-id="2">Item 2</li>
  <li draggable="true" data-id="3">Item 3</li>
</ul>

dragstartでドラッグ元を記録

dragstartでドラッグしたidをdataTransferに保存し、視覚的なフィードバックとして"dragging"クラスを適用します。effectAllowed="move"は、ブラウザーに対してこれがコピーではなく並べ替え操作であることを伝えるため、カーソルとdropEffectが移動操作を反映します。

list.addEventListener("dragstart", (e) => {
  const li = e.target.closest("li");
  if (!li) return;
  e.dataTransfer.setData("text/plain", li.dataset.id);
  e.dataTransfer.effectAllowed = "move";
  li.classList.add("dragging");
});

dragoverでドロップを許可

リストにイベント委譲を設定し、preventDefaultを呼び出して、dropEffectを"move"に設定します。e.target.closest("li")を使用してカーソルが重なっている行を見つければ、リスト全体で同じハンドラーを使用できます。

挿入位置の計算

ドラッグした項目をカーソルが重なっている行の上と下のどちらに配置するかを決めるには、カーソルのY座標と行の垂直方向の中央位置を比較します。const before = (e.clientY - rect.top) < rect.height / 2。before=trueの場合はinsertBefore、falseの場合はinsertAfterで挿入します。

function getInsertBefore(target, clientY) {
  const rect = target.getBoundingClientRect();
  return clientY < rect.top + rect.height / 2;
}

dropでDOMを並べ替え

dropハンドラーで、idからドラッグした要素を検索し、カーソルの下にある対象行を取得します。対象の上半分と下半分のどちらにカーソルがあったかに応じて、list.insertBefore(dragged, target)またはlist.insertBefore(dragged, target.nextSibling)を呼び出します。

dragendでスタイルをクリーンアップ

ドロップに成功した場合でも、ユーザーがEscapeを押した場合でも、dragendは常にドラッグ元で発生します。これを使って"dragging"クラスとドロップ先のハイライトを削除し、リストを待機状態に戻します。

list.addEventListener("dragend", () => {
  list.querySelectorAll(".dragging, .over").forEach((el) => {
    el.classList.remove("dragging", "over");
  });
});

視覚的なドロップインジケーター

カーソルが重なっている行にCSSの疑似要素を使って細い線を表示し、項目が配置される位置を示します。dragoverハンドラーがカーソルの位置に基づいて"over-top"または"over-bottom"クラスを切り替えます。ユーザーはボタンを離す前に挿入位置を確認できます。

モデルとの同期

ドロップ後に、DOMから新しい順序を導出します。const order = Array.from(list.children).map((li) => li.dataset.id)。この配列をサーバーに送信するか、stateに保存します。高速なドラッグ操作ではDOMと並行して管理するインデックスがずれるため、決して別のインデックスを維持しようとはしないでください。

キーボード操作の代替手段

Up/Downハンドラーを追加し、insertBeforeでフォーカス中の項目を移動できるようにします。aria-live領域を通じて移動を「項目を上に移動しました。位置は2番目です」と通知します。キーボード利用者は視覚的なドラッグ操作を行わずに同じ機能を使えるため、アクセシビリティに不可欠です。

タッチ操作に対応したフォールバック

モバイルではネイティブのドラッグ操作をPointer Eventsに置き換えます。pointerdownで行を取得し、pointermoveでCSS transformを使って移動させ、pointerupで下にある行をヒットテストして並べ替えます。SortableJSのようなライブラリを使えば、入力方式をまたいだこのパターンを実装できます。

理解度チェック

挿入位置を、カーソルとカーソルが重なっている行の垂直方向の中央位置との関係から計算するのはなぜですか?

まとめ

堅牢な並べ替えリストは、draggable="true"と、dragstart(idを記録し、effectAllowed=moveを設定)、dragover(preventDefaultとインジケーター位置の設定)、drop(中央位置から求めたスロットでinsertBefore)、dragend(クリーンアップ)を組み合わせます。ドロップ後は必ずDOMから新しい順序を導出し、アクセシビリティのためにキーボード操作のフォールバックも用意してください。

よくある質問

「実践:ドラッグで並べ替えるリスト」レッスンは無料ですか?

はい。「実践:ドラッグで並べ替えるリスト」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、HTML Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 HTML Academyコースには全4レッスンが含まれています。

「実践:ドラッグで並べ替えるリスト」で何を学びますか?

Drag and Drop APIで並べ替え可能なリストを作成します ブラウザで直接実行するハンズオンコードでHTML Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

HTML Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのHTML Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン4/4です。

「実践:ドラッグで並べ替えるリスト」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このHTML Academyレッスンでコードを書いて実行できますか?

はい。すべてのHTML Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. draggable属性とdragstartイベント
  2. dragoverとdropイベント
  3. dataTransferオブジェクト
  4. 実践:ドラッグで並べ替えるリスト
← HTML Academyに戻る