How DataTransfer Passes Files and Text in JavaScript
The HTML5 Drag and Drop API relies on the DataTransfer
object to hold and transfer data between a drag source and a drop zone.
This object acts as a shared clipboard during the drag operation,
holding data types, format specifications, and file lists. By listening
to specific drag events, JavaScript developers can populate the
DataTransfer object with plain text, HTML, custom data, or
binary files, and subsequently extract those payloads when the user
releases the mouse over a designated drop target.
The Role of the DataTransfer Object
When a drag operation begins, the browser creates a
DataTransfer instance accessible via the
dataTransfer property of the DragEvent. This
object serves as the bridge between the element being dragged (the
source) and the element receiving the drop (the target). It persists
throughout the drag-and-drop lifecycle, exposing methods to set and
retrieve data, configure visual drag feedback, and determine allowed
drop effects such as copying or moving.
Setting Up Drop Zones
For an element to accept dragged data or files, it must be designated
as a drop zone. Browsers prevent drops on most elements by default, so
the default behavior must be canceled in the dragover event
handler.
const dropZone = document.querySelector('#drop-zone');
dropZone.addEventListener('dragover', (event) => {
// Prevent default to allow drop
event.preventDefault();
event.dataTransfer.dropEffect = 'copy';
});Passing Text and Custom Strings
Text transfer relies on key-value pairs assigned via MIME types. The
drag source uses setData() during the
dragstart event, and the drop target reads the data using
getData() during the drop event.
Setting the Data:
draggableElement.addEventListener('dragstart', (event) => { event.dataTransfer.setData('text/plain', 'Sample text payload'); event.dataTransfer.setData('text/html', '<strong>Formatted Text</strong>'); });Reading the Data:
dropZone.addEventListener('drop', (event) => { event.preventDefault(); const textData = event.dataTransfer.getData('text/plain'); console.log('Received text:', textData); });
Common MIME types include text/plain,
text/html, and text/uri-list. Developers can
also define custom MIME types (e.g.,
application/my-custom-type) to pass serialized JSON strings
between elements.
Passing Files to Drop Zones
When users drag files directly from their operating system’s file
manager into the browser, the DataTransfer object captures
them in two properties: files and items.
Using the files
Property
The dataTransfer.files property returns a standard
FileList containing File objects. These can be
inspected, converted, or uploaded using the FileReader API,
fetch(), or FormData.
dropZone.addEventListener('drop', (event) => {
event.preventDefault();
const files = event.dataTransfer.files;
for (const file of files) {
console.log(`File Name: ${file.name}, Size: ${file.size} bytes`);
}
});Using the items
Property
The dataTransfer.items property provides a
DataTransferItemList, offering lower-level access to both
files and string data. This is particularly useful for checking file
types before reading them or for accessing directories using
webkitGetAsEntry().
dropZone.addEventListener('drop', (event) => {
event.preventDefault();
if (event.dataTransfer.items) {
for (const item of event.dataTransfer.items) {
if (item.kind === 'file') {
const file = item.getAsFile();
console.log('Extracted file via items:', file.name);
}
}
}
});Security Considerations
For security reasons, data stored inside DataTransfer is
subject to restrictions based on the event phase. During
dragenter and dragover events, the data
payload is in a protected mode; scripts can inspect data types (via
types) and file counts, but they cannot read the actual
string contents or file data using getData() or
files. The data only becomes readable once the
drop event fires.