HTML Academy · Lezione

Creare una lista riordinabile con il trascinamento

Creare una lista riordinabile con la Drag and Drop API

Lezione 4 di 413 passaggi

Creare una lista riordinabile con il trascinamento è una lezione HTML Academy gratuita su CoddyKit. Questa è la lezione 4 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento HTML Academy, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso HTML Academy include 4 lezioni in totale.

Panoramica del pattern

Per creare un elenco riordinabile tramite trascinamento, renda ogni elemento trascinabile, memorizzi l'id dell'elemento trascinato in dataTransfer durante dragstart e, al rilascio, inserisca l'elemento trascinato prima o dopo la destinazione. Il DOM e il modello rimangono sincronizzati se ricostruisce l'ordine a partire dal DOM dopo ogni rilascio.

Markup

Visualizzi un elenco piatto in cui ogni li contiene draggable="true" e un data-id. Mantenere gli id sugli elementi significa che i gestori del trascinamento non devono interrogare un archivio di stato separato per identificare gli elementi: l'elemento stesso è la fonte di verità.

<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 registra l'origine

Durante dragstart, memorizzi l'id dell'elemento trascinato in dataTransfer e applichi una classe "dragging" per fornire un feedback visivo. effectAllowed="move" comunica al browser che si tratta di un riordino e non di una copia, perciò il cursore e dropEffect riflettono un'operazione di spostamento.

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 consente il rilascio

Ascolti gli eventi sull'elenco (event delegation), chiami preventDefault e imposti dropEffect su "move". Utilizzi e.target.closest("li") per trovare la riga sotto il cursore, così lo stesso gestore funziona per l'intero elenco.

Calcolo della posizione di inserimento

Per decidere se l'elemento trascinato debba essere posizionato sopra o sotto la riga sotto il cursore, confronti la coordinata Y del cursore con il punto medio verticale della riga: const before = (e.clientY - rect.top) < rect.height / 2. before=true significa inserire con insertBefore, mentre false significa inserire con insertAfter.

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

drop riordina il DOM

Nel gestore di drop, cerchi l'elemento trascinato tramite il suo id e la riga di destinazione sotto il cursore. Chiami list.insertBefore(dragged, target) oppure list.insertBefore(dragged, target.nextSibling) a seconda della metà della destinazione che era sotto il cursore.

dragend ripulisce gli stili

Indipendentemente dal fatto che il rilascio sia riuscito o che l'utente abbia premuto Escape, dragend viene sempre attivato sull'origine. Lo utilizzi per rimuovere la classe "dragging" e tutte le evidenziazioni della destinazione, così l'elenco torna allo stato inattivo.

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

Indicatore visivo di rilascio

Mostri una linea sottile nel punto in cui verrà posizionato l'elemento utilizzando uno pseudo-elemento CSS sulla riga sotto il cursore, attivato tramite la classe "over-top" o "over-bottom" che il gestore di dragover imposta in base alla posizione del cursore. L'utente vede il punto di inserimento prima di rilasciare l'elemento.

Sincronizzazione del modello

Dopo il rilascio, ricavi il nuovo ordine dal DOM: const order = Array.from(list.children).map((li) => li.dataset.id). Invii questo array al server o lo memorizzi nello stato: non cerchi mai di mantenere un indice parallelo insieme al DOM, perché si desincronizza durante i trascinamenti rapidi.

Alternativa da tastiera

Aggiunga gestori Up/Down che spostino l'elemento attivo tramite insertBefore. Comunichi lo spostamento tramite una regione aria-live ("Item moved up to position 2"). Gli utenti che usano la tastiera ottengono la stessa funzionalità senza dover ricorrere al trascinamento visivo, un aspetto essenziale per l'accessibilità.

Fallback per dispositivi touch

Per i dispositivi mobili, sostituisca il trascinamento nativo con i Pointer Events: durante pointerdown acquisisca la riga, durante pointermove la trasli con CSS transform e durante pointerup individui tramite hit-test la riga sottostante e riordini gli elementi. Librerie come SortableJS incapsulano questo pattern per diversi tipi di input.

Verifica delle conoscenze

Perché calcoliamo la posizione di inserimento in base alla posizione del cursore rispetto al punto medio verticale della riga sotto il cursore?

Riepilogo

Un elenco riordinabile robusto combina draggable="true" + dragstart (registrazione dell'id, effectAllowed=move) + dragover (preventDefault + posizione dell'indicatore) + drop (insertBefore nello spazio calcolato in base al punto medio) + dragend (ripulitura). Ricavi sempre il nuovo ordine dal DOM dopo il rilascio e fornisca un'alternativa da tastiera per l'accessibilità.

Gratis per iniziare

Impara HTML con un tutor IA — gratis

Scrivi ed esegui vero codice nel tuo browser, ricevi aiuto istantaneo da un tutor IA disponibile 24/7, e riprendi da dove hai lasciato sul web o nell'app.

Corsi
40
Lezioni
159

Domande Frequenti

La lezione «Creare una lista riordinabile con il trascinamento» è gratuita?

Sì — il testo completo di «Creare una lista riordinabile con il trascinamento» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso HTML Academy, passa a CoddyKit PRO. Il corso HTML Academy include 4 lezioni in totale.

Cosa imparerò in «Creare una lista riordinabile con il trascinamento»?

Creare una lista riordinabile con la Drag and Drop API Eserciti HTML Academy con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.

Ho bisogno di esperienza per iniziare HTML Academy?

Non è richiesta alcuna esperienza precedente. HTML Academy su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 4 di 4.

Quanto tempo richiede la lezione «Creare una lista riordinabile con il trascinamento»?

La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.

Posso scrivere ed eseguire codice in questa lezione HTML Academy?

Sì. Ogni lezione HTML Academy include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.

Tutte le lezioni di questo corso

  1. Attributo draggable ed evento dragstart
  2. Eventi dragover e drop
  3. Oggetto dataTransfer
  4. Creare una lista riordinabile con il trascinamento
← Torna a HTML Academy