Il drag and drop è un'interazione che l'utente svolge trascinando e rilasciando gli elementi della pagina. Storicamente questo tipo di interazione era già disponibile in Internet Explorer 6, ma solo con HTML5 le API per il drag and drop sono state standardizzate.
Rendere gli elementi trascinabili
In HTML5 gli elementi che useranno il drag and drop vengono definiti come tali tramite l'attributo draggable
:
<div id="test" draggable="true">Draggable Div</div>
Eventi del drag and drop
Ci sono diversi eventi DOM che gestiscono il drag and drop:
dragstart
– Questo evento ha luogo quando un elemento comincia ad essere trascinato dall'utente. Non ha luogo quando un file viene trascinato nella finestra del browser.drag
– Questo evento continua ad essere attivo durante tutta la fase del trascinamento.dragenter
– Questo evento ha luogo quando l'elemento trascinato entra nell'elemento di destinazione. Il gestore di eventi deve essere impostato sull'elemento di destinazione.dragleave
– Questo evento ha luogo quando l'elemento trascinato lascia l'elemento di destinazione.dragover
– Questo evento continua ad essere attivo quando l'elemento trascinato è sopra l'elemento di destinazione.drop
– Questo evento ha luogo quando l'elemento trascinato o il file viene rilasciato.dragend
– Questo evento ha luogo quando il trascinamento di un elemento è stato completato.
Esempio:
const draggableElement = document.getElementById('test');
draggableElement.addEventListener('dragstart', e => {
console.log('Drag Interaction Started!');
});
L'oggetto DataTransfer
Quando viene inizializzata un'azione di trascinamento l'oggetto DataTransfer
viene creato e associato a tale azione. Questo oggetto
conserva sia dati che informazioni sull'evento di trascinamento.
dropEffect
– Il tipo di interazione che il browser deve gestire. I valori possibili sonocopy
,move
,link
enone
.effectAllowed
– I tipi consentiti per l'interazione. I valori possibili sonocopy
,move
,link
,copyLink
,copyMove
,linkMove
,all
,none
euninitialized
(predefinito).files
– UnaFileList
contenente oggettiFile
, utile se si trascinano file nella finestra del browser.types
– Una lista dei formati memorizzati nell'oggettoDataTransfer
.setData(format, data)
– Imposta un tipo di dati (ad esempiotext/html
) e il suo valore.getData(format)
– Reperisce i dati per il formato specificato.clearData(format)
– Elimina i dati per il formato specificato.setDragImage(imgElement, x, y)
– Specifica un'immagine come elemento del DOM (non come percorso) da visualizzare durante il trascinamento. Le coordinate indicano la posizione dell'immagine rispetto al puntatore del mouse.
Esempio: trascinamento di file
Partiamo dalla seguente marcatura:
<div id="files">Drop a .txt file here</div>
<pre id="file-content"></pre>
Scriveremo il seguente codice:
const dropZone = document.getElementById('files');
const fileContainer = document.getElementById('file-content');
dropZone.addEventListener('dragover', e => {
e.preventDefault();
e.dataTransfer.dropEffect = 'copy';
}, false);
dropZone.addEventListener('dragenter', e => {
this.className = 'over';
}, false);
dropZone.addEventListener('dragleave', e => {
this.className = '';
}, false);
dropZone.addEventListener('drop', e => {
e.preventDefault();
this.className = '';
const fileList = e.dataTransfer.files;
if (fileList.length > 0) {
readTextFile(fileList[0]);
}
}, false);
A questo punto utilizziamo le API FileReader
per leggere il contenuto del file:
const readTextFile = file => {
const reader = new FileReader();
reader.onloadend = e => {
if (e.target.readyState == FileReader.DONE) {
const content = reader.result;
fileContainer.innerHTML = `File: ${file.name} ${content}`;
}
};
reader.readAsBinaryString(file);
};
Supporto nei browser
- IE10+ (con supporto ai file)
- IE Mobile 10
- Firefox 3.5+
- Chrome 4.0+
- Safari 3.1+
- Opera 12+