Attributo HTML draggable
L'attributo HTML draggable è un attributo enumerato che specifica se un elemento è trascinabile o meno. Scopri su quali elementi può essere usato.
L'attributo HTML draggable è un attributo enumerato che specifica se un elemento può essere trascinato dall'utente con un dispositivo di puntamento (mouse o tocco). È il punto di ingresso all'HTML Drag and Drop API, che permette di spostare elementi, testo, file o dati personalizzati da un punto all'altro di una pagina.
Impostare draggable="true" rende semplicemente un elemento selezionabile per il trascinamento. Per spostarlo effettivamente e rilasciarlo in un punto utile, è necessario gestire anche gli eventi di drag and drop e trasportare le informazioni tramite l'object dataTransfer — entrambi trattati di seguito.
Questo attributo può essere usato su qualsiasi elemento HTML. Fa parte degli Attributi globali, quindi funziona insieme ad altri attributi globali come contenteditable.
Valori
L'attributo draggable può assumere i seguenti valori:
true— l'elemento può essere trascinato.false— l'elemento non può essere trascinato. Utile per disabilitare il trascinamento predefinito di immagini e link.auto— utilizza il comportamento predefinito del browser per quell'elemento. In pratica ciò significa che immagini e link sono trascinabili, mentre la maggior parte degli altri elementi non lo è. Poichéautosi limita a rimandare al comportamento predefinito, viene raramente scritto esplicitamente; ometteredraggableproduce lo stesso risultato.
<tag draggable="true|false|auto"></tag>Nota:
draggablenon è un attributo boolean. È necessario scrivere il valore esplicitamente —draggableda solo odraggable=""non è valido. Usare sempredraggable="true"odraggable="false".
Come funziona il drag and drop
Un'interazione di drag and drop genera una sequenza di eventi, suddivisi tra l'elemento trascinato (sorgente) e l'elemento su cui viene rilasciato (destinazione):
| Evento | Si attiva su | Quando |
|---|---|---|
dragstart | sorgente | L'utente inizia a trascinare l'elemento. Imposta i dati qui con dataTransfer.setData(). |
drag | sorgente | Ripetutamente mentre l'elemento viene trascinato. |
dragenter | destinazione | L'elemento trascinato entra in un'area di rilascio valida. |
dragover | destinazione | Ripetutamente mentre l'elemento si trova sopra un'area di rilascio. Chiamare preventDefault() qui. |
dragleave | destinazione | L'elemento trascinato lascia l'area di rilascio. |
drop | destinazione | L'elemento viene rilasciato sopra la destinazione. Leggi i dati qui con dataTransfer.getData(). |
dragend | sorgente | Il trascinamento termina (sia che sia stato rilasciato correttamente sia che sia stato annullato). |
L'object dataTransfer
Ogni evento di trascinamento espone event.dataTransfer, il canale usato per passare i dati dalla sorgente alla destinazione:
event.dataTransfer.setData(format, data)— memorizza una string durantedragstart. Ilformatè solitamente un tipo MIME come"text/plain"(il codice più vecchio usa"Text", che funziona ancora).event.dataTransfer.getData(format)— legge quella string durantedrop.
Poiché i dati diventano disponibili solo al drop, il pattern tipico è memorizzare l'id di un elemento (o qualsiasi identificatore) in dragstart, quindi cercarlo e spostarlo in drop.
Perché preventDefault() è obbligatorio
Per impostazione predefinita, la maggior parte degli elementi non è una destinazione di rilascio valida, quindi il browser annulla il drop. Per fare in modo che un elemento diventi una zona di rilascio è necessario chiamare event.preventDefault() nel suo gestore dragover — questo comunica al browser "sì, il rilascio è consentito qui." È anche comune chiamare preventDefault() nel gestore drop per impedire l'azione predefinita del browser (ad esempio, navigare verso un link trascinato o aprire un file rilasciato).
Se si dimentica preventDefault() in dragover, l'evento drop non si attiva mai e non succede nulla.
Esempio (gestori inline)
Questo esempio usa attributi di gestione eventi inline (ondragstart, ondragover, ondrop). È conciso ma mescola JavaScript nel markup:
<!DOCTYPE HTML>
<html>
<head>
<title>Title of the document</title>
<style>
#rectId {
width: 350px;
height: 70px;
padding: 10px;
border: 1px solid #aaaaaa;
}
</style>
<script>
function allowDrop(event) {
event.preventDefault(); // Allow dropping
}
function drag(event) {
// Store the dragged element's ID in the dataTransfer object
event.dataTransfer.setData("text/plain", event.target.id);
}
function drop(event) {
event.preventDefault();
var data = event.dataTransfer.getData("text/plain"); // Retrieve the ID
event.target.appendChild(document.getElementById(data));
}
</script>
</head>
<body>
<div id="rectId" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
<br />
<p id="dragId" draggable="true" ondragstart="drag(event)">
This is a draggable paragraph. Drag this item to the rectangle.
</p>
</body>
</html>Esempio (con addEventListener)
Per un codice manutenibile, mantieni il markup pulito e collega i gestori in JavaScript con addEventListener. Questo è l'approccio consigliato:
<!DOCTYPE HTML>
<html>
<head>
<title>Title of the document</title>
<style>
#dropzone {
width: 350px;
height: 70px;
padding: 10px;
border: 1px solid #aaaaaa;
}
</style>
</head>
<body>
<div id="dropzone"></div>
<br />
<p id="item" draggable="true">
This is a draggable paragraph. Drag this item to the rectangle.
</p>
<script>
const item = document.getElementById("item");
const dropzone = document.getElementById("dropzone");
// Source: store the dragged element's ID when the drag begins.
item.addEventListener("dragstart", (event) => {
event.dataTransfer.setData("text/plain", event.target.id);
});
// Target: allow dropping by preventing the default handling.
dropzone.addEventListener("dragover", (event) => {
event.preventDefault();
});
// Target: move the element into the drop zone.
dropzone.addEventListener("drop", (event) => {
event.preventDefault();
const id = event.dataTransfer.getData("text/plain");
const dragged = document.getElementById(id);
event.currentTarget.appendChild(dragged);
});
</script>
</body>
</html>Accessibilità
L'attributo draggable non fornisce alcun supporto per tastiera o screen reader di per sé — il drag and drop è un'interazione esclusivamente tramite puntatore. Gli utenti che navigano con la tastiera o con tecnologie assistive non possono eseguire un trascinamento nativo.
Se il drag and drop è l'unico modo per completare un'azione, offri sempre un'alternativa accessibile (ad esempio, pulsanti "Sposta su / Sposta giù", un menu di selezione o copia/incolla). Tratta il drag and drop nativo come un miglioramento, non come l'unico percorso.