Drag and Drop API HTML5
L'API Drag and Drop di HTML5 permette di implementare il trascinamento di elementi tra zone della pagina o da/verso il file system locale. Standardizzata, supportata da tutti i browser desktop, è la base per interfacce moderne come Trello, drag di file da finestra esterna, riordinamento di liste. Vediamo come implementarla in modo robusto.
Concetti base
Per rendere un'elemento trascinabile aggiungi l'attributo draggable="true". La drag-and-drop è gestita da una serie di eventi: dragstart (inizio drag), drag (durante), dragenter, dragover, dragleave (sulla drop zone), drop (rilascio), dragend (fine). L'oggetto DataTransfer trasporta i dati tra origine e destinazione. Per abilitare il drop su una zona devi sempre prevenire il default di dragover.
DataTransfer
DataTransfer è l'oggetto centrale: contiene i dati trasferiti tra origine e destinazione. Metodi principali: setData(format, data) per associare dati, getData(format) per leggerli, setDragImage per personalizzare l'icona durante il drag. Per trasferire file da finestra esterna usa la proprietà files con la FileList. Supporta tipi MIME standard come text/plain, text/html, application/json e tipi custom.
Drag tra finestre browser
L'API drag and drop supporta trascinamento tra finestre del browser e dal sistema operativo. Trascinare un file dall'Esplora Risorse a una drop zone web funziona out-of-the-box: gestisci drop con dataTransfer.files che fornisce una FileList. Per drop di immagini da altre pagine web, dataTransfer.items contiene DataTransferItem con kind 'file' o 'string'. Pattern comune negli editor web: drag and drop di immagini direttamente dal desktop verso l'area di editing, con upload automatico al server. UX moderna che gli utenti si aspettano.
Effects e cursor
L'attributo effectAllowed (sul source) e dropEffect (sul target) controllano il feedback visivo del drag: 'copy', 'move', 'link', 'none'. Il cursore cambia in base alla combinazione. Esempio: source con effectAllowed="copyMove", target con dropEffect="move" mostra cursore "spostamento". Per UX professionale imposta sempre questi attributi correttamente in dragstart e dragover. Combina con classi CSS sul target durante dragenter/dragleave per evidenziare visivamente la drop zone, segnalando all'utente dove può rilasciare l'elemento trascinato.
Sortable lists
Pattern comune: liste riordinabili via drag and drop. Implementazione manuale: ogni li ha draggable=true, gestisci dragstart/dragover/drop per spostare elementi. Calcola posizione di drop in base a mouse Y vs bounding box dei li. Animazioni smooth con CSS transition + transform. Per casi complessi, librerie come SortableJS, react-dnd, vue-draggable astraggono dettagli e gestiscono touch su mobile. SortableJS è particolarmente popolare: ~30KB, zero dipendenze, API semplice, supporto cross-browser e cross-input completo. Quando hai bisogno di drag complessi multi-list con animazioni, ne vale la pena.
Touch e Pointer Events
L'API drag-and-drop HTML5 non funziona su touch (mobile). Per drag and drop cross-device usa Pointer Events: pointerdown/pointermove/pointerup unificano mouse e touch. Implementi tu la logica di drag, ma con benefit della uniformità mouse+touch+pen. Combinato con CSS touch-action: none sui draggable per disabilitare scroll durante il drag. Librerie come Interact.js gestiscono tutto questo offrendo API più semplice. Per produzione, valuta sempre se l'esperienza touch è critica: se sì investi in Pointer Events o librerie, altrimenti accetta che drag-and-drop sia desktop-only feature.
Use case ricorrenti
Use case ricorrenti per drag and drop: kanban board (Trello-like), riordinamento liste (todo list), upload file con dropzone, editor a blocchi (Notion-like), assegnazione cards a colonne, file manager browser-based, organizing email in folders. Per ognuno la libreria dedicata accelera notevolmente lo sviluppo. SortableJS per sortable list cross-platform, Dropzone.js per upload con preview, react-dnd per React complex scenarios, vuedraggable per Vue. Test routine cross-device: drag funziona perfettamente su desktop mouse, ma touch su mobile richiede pointer events o librerie che astraggono. Pianifica fallback UX (es. bottoni up/down) per device touch se drag-and-drop è critico.
Procedura passo-passo
- Aggiungi draggable="true" all'elemento da trascinare.
- Aggancia evento dragstart: e.dataTransfer.setData('text/plain', 'valore').
- Sulla drop zone gestisci dragover: e.preventDefault() per abilitare il drop.
- Sulla drop zone gestisci drop: const data = e.dataTransfer.getData('text/plain').
- Personalizza feedback visivo con dragenter/dragleave (es. evidenziare la zona).
- Per file drop da OS: e.dataTransfer.files dà la FileList.
- Su mobile usa Pointer Events o librerie come SortableJS.
Errori comuni e come risolverli
- preventDefault mancante in dragover: senza di esso drop non viene mai chiamato; aggiungi sempre.
- setData con tipo errato: ricorda di usare lo stesso format in setData e getData.
- Drag su mobile: l'API HTML5 non funziona su touch; usa Pointer Events per mobile.
- UX poveri: senza feedback visivo l'utente non capisce dove può rilasciare; usa hover state.
- Drop fuori target: gestisci dragend per resettare lo stato se l'utente rilascia fuori da zone valide.
Domande frequenti
D: Drag and drop funziona su mobile?
R: Limitatamente. Per touch usa Pointer Events o librerie come SortableJS che astraggono entrambi i mondi.
D: Posso trascinare file dal desktop?
R: Sì, l'evento drop espone dataTransfer.files con la FileList.
D: Quale formato per i dati trasferiti?
R: Tipi MIME standard (text/plain, text/html) per interop, tipi custom per app interne.
D: Posso personalizzare l'icona del drag?
R: Sì, con e.dataTransfer.setDragImage(element, offsetX, offsetY).
Hai bisogno di aiuto?
Se vuoi sviluppo web con il team di G Tech Group, scrivici tramite il modulo di contatto.