Signatur
Beschreibung
Das drop-Event gehört zur HTML Drag and Drop API. Es wird auf dem Element ausgelöst, über dem der Nutzer die Maustaste loslässt. Voraussetzung: Das Element hat sich vorher als gültiges Ablageziel gemeldet. Das Event-Objekt ist ein DragEvent. Über dessen Eigenschaft dataTransfer erreichen Sie die übertragenen Daten, also Text, URLs, eigene MIME-Typen oder Dateien.
Wichtig: Standardmäßig ist ein Element kein Ablageziel. Damit drop überhaupt ausgelöst wird, müssen Sie im dragover-Handler (und am besten auch in dragenter) event.preventDefault() aufrufen. Fehlt dieser Aufruf, kommt das Event nie an.
Auch im drop-Handler selbst sollten Sie preventDefault() aufrufen. Sonst führt der Browser seine Standardaktion aus: Er öffnet zum Beispiel eine abgelegte Datei oder navigiert zu einem abgelegten Link.
Registrieren können Sie den Handler per addEventListener("drop", …) oder über die Eigenschaft ondrop. Das Event steigt im DOM auf (bubbles) und kann abgebrochen werden (cancelable). Typische Einsatzfälle sind Datei-Upload-Zonen, sortierbare Listen und Kanban-Boards.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $type Pflicht | string | Der Event-Name "drop". |
|
| $handler Pflicht | (event: DragEvent) => void | Callback-Funktion. Sie erhält ein DragEvent mit dataTransfer, clientX/clientY und target. |
|
| $options | boolean | AddEventListenerOptions | false | Optionen wie capture, once, passive oder signal. Setzen Sie passive: true hier nicht, sonst ist preventDefault() wirkungslos. |
Rückgabewert
addEventListener gibt nichts zurück. Der Handler erhält ein DragEvent.Beispiele
Datei-Upload-Zone mit addEventListener
const zone = document.querySelector('#dropzone');
// Ohne preventDefault in dragover wird drop nie ausgelöst
zone.addEventListener('dragover', (e) => {
e.preventDefault();
e.dataTransfer.dropEffect = 'copy';
zone.classList.add('aktiv');
});
zone.addEventListener('dragleave', () => zone.classList.remove('aktiv'));
zone.addEventListener('drop', async (e) => {
e.preventDefault(); // verhindert, dass der Browser die Datei öffnet
zone.classList.remove('aktiv');
const dateien = [...e.dataTransfer.files];
for (const datei of dateien) {
console.log(`${datei.name} (${datei.size} Bytes)`);
const form = new FormData();
form.append('datei', datei);
await fetch('/upload', { method: 'POST', body: form });
}
});
Listenelemente zwischen Spalten verschieben
document.querySelectorAll('.karte').forEach((karte) => {
karte.draggable = true;
karte.addEventListener('dragstart', (e) => {
e.dataTransfer.setData('text/plain', karte.id);
e.dataTransfer.effectAllowed = 'move';
});
});
document.querySelectorAll('.spalte').forEach((spalte) => {
spalte.addEventListener('dragover', (e) => e.preventDefault());
spalte.addEventListener('drop', (e) => {
e.preventDefault();
const id = e.dataTransfer.getData('text/plain');
const karte = document.getElementById(id);
if (karte) {
spalte.appendChild(karte);
console.log(`Karte ${id} nach ${spalte.dataset.name} verschoben`);
}
});
});
ondrop-Eigenschaft und Entfernen des Listeners
const ziel = document.querySelector('#ziel');
ziel.ondragover = (e) => e.preventDefault();
ziel.ondrop = (e) => {
e.preventDefault();
console.log('Abgelegt:', e.dataTransfer.getData('text/plain'));
};
// Variante mit addEventListener, die sich wieder entfernen lässt
const beiDrop = (e) => {
e.preventDefault();
console.log('Einmaliger Drop');
ziel.removeEventListener('drop', beiDrop);
};
ziel.addEventListener('drop', beiDrop);
// Handler über die Eigenschaft deaktivieren
// ziel.ondrop = null;
// Wichtig · Fallstricke
- Häufigster Fehler: Wenn
dragovernicht mitpreventDefault()abgebrochen wird, wirddropnie ausgelöst. - Rufen Sie auch in
droppreventDefault()auf. Sonst öffnet der Browser abgelegte Dateien oder Links, besonders in Firefox. - Mit
dataTransfer.getData()können Sie Daten nur indrop(und indragstart) lesen. Indragoverist nurdataTransfer.typessichtbar (geschützter Modus). - Sicherheit: Abgelegte Inhalte können aus fremden Quellen stammen. Fügen Sie Werte aus
getData('text/html')nie ungeprüft perinnerHTMLein, sonst droht XSS. Nutzen SietextContentoder bereinigen Sie das HTML vorher. Prüfen Sie Dateitypen und -größen serverseitig. dragleavewird auch beim Wechsel auf Kindelemente ausgelöst. Hervorhebungen können deshalb flackern. Abhilfe schafft ein Zähler oderpointer-events: noneauf den Kindelementen während des Ziehens.- Auf Touch-Geräten wird die native Drag-and-Drop-API nur eingeschränkt unterstützt (iOS Safari erst ab Version 11, und nicht in allen Browsern). Planen Sie dort gegebenenfalls eine Umsetzung mit Pointer Events ein.
- Für Ordner und Dateien liefert
dataTransfer.itemsmitgetAsFileSystemHandle()bzw.webkitGetAsEntry()mehr Möglichkeiten alsfiles.