Signatur
Beschreibung
Das dragover-Ereignis gehört zur HTML Drag and Drop API. Es wird auf dem Ablageziel (dem Element unter dem Mauszeiger) ausgelöst, und zwar nicht nur einmal, sondern fortlaufend, solange der Zeiger während des Ziehens über dem Element bleibt. Es ist bubbelnd und abbrechbar; das Ereignisobjekt ist ein DragEvent mit der Eigenschaft dataTransfer.
Die wichtigste Aufgabe von dragover: Ein Element wird erst durch event.preventDefault() zu einem gültigen Ablageziel. Standardmäßig lehnen fast alle Elemente das Ablegen ab. Nur wenn sowohl in dragenter als auch in dragover die Standardaktion verhindert wird, feuert beim Loslassen das drop-Ereignis.
Zusätzlich kannst du in dragover über event.dataTransfer.dropEffect festlegen, welcher Cursor angezeigt wird ("copy", "move", "link" oder "none"), und abhängig von der Zeigerposition (clientX/clientY) visuelles Feedback geben, etwa eine Einfügemarkierung in sortierbaren Listen.
Registrieren kannst du den Handler per addEventListener("dragover", ...) oder über die Eigenschaft element.ondragover bzw. das HTML-Attribut ondragover.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $type Pflicht | string | Der Ereignisname "dragover". |
|
| $handler Pflicht | (event: DragEvent) => void | Rückruffunktion, die ein DragEvent erhält. Wichtige Eigenschaften: dataTransfer, target, clientX, clientY. |
|
| $options | boolean | AddEventListenerOptions | false | Optionen wie capture, once, signal. Nicht passive: true setzen – sonst wirkt preventDefault() nicht. |
Rückgabewert
addEventListener gibt undefined zurück. Der Rückgabewert des Handlers wird ignoriert (außer bei ondragover, wo return false wie preventDefault() wirkt).Beispiele
Ablagezone für Dateien aktivieren
const zone = document.querySelector('#dropzone');
zone.addEventListener('dragover', (event) => {
// Ohne preventDefault() wird drop nie ausgelöst
event.preventDefault();
event.dataTransfer.dropEffect = 'copy';
zone.classList.add('is-over');
});
zone.addEventListener('dragleave', () => zone.classList.remove('is-over'));
zone.addEventListener('drop', (event) => {
event.preventDefault();
zone.classList.remove('is-over');
const names = [...event.dataTransfer.files].map((f) => f.name);
console.log('Abgelegt:', names);
});
Nur bestimmte Datentypen akzeptieren
const trash = document.querySelector('#papierkorb');
trash.addEventListener('dragover', (event) => {
// In dragover sind nur die Typen lesbar, nicht die Daten selbst
if (event.dataTransfer.types.includes('application/x-task-id')) {
event.preventDefault();
event.dataTransfer.dropEffect = 'move';
}
// sonst: kein preventDefault -> Ablegen verboten
});
trash.addEventListener('drop', (event) => {
const id = event.dataTransfer.getData('application/x-task-id');
console.log(`Aufgabe ${id} gelöscht`);
});
Sortierbare Liste mit Einfügeposition
const list = document.querySelector('#liste');
let dragged = null;
list.addEventListener('dragstart', (e) => { dragged = e.target; });
list.addEventListener('dragover', (e) => {
e.preventDefault();
const item = e.target.closest('li');
if (!item || item === dragged) return;
const { top, height } = item.getBoundingClientRect();
const after = e.clientY > top + height / 2;
item.parentNode.insertBefore(dragged, after ? item.nextSibling : item);
});
Handler über die on-Property setzen und wieder entfernen
const box = document.querySelector('.ziel');
box.ondragover = (event) => {
event.preventDefault();
};
// Später Ablegen wieder deaktivieren
box.ondragover = null;
// Variante mit addEventListener/removeEventListener
const onOver = (e) => e.preventDefault();
box.addEventListener('dragover', onOver);
box.removeEventListener('dragover', onOver);
// Wichtig · Fallstricke
- Häufigster Fehler:
preventDefault()indragoververgessen – dann wirddropnie ausgelöst. - Hohe Frequenz: Das Ereignis feuert mehrmals pro Sekunde, auch ohne Mausbewegung. Aufwendige DOM-Operationen oder Layout-Abfragen drosseln (z. B. mit
requestAnimationFrame) oder nur bei Zielwechsel ausführen. - Geschützter Modus: In
dragoverliefertdataTransfer.getData()aus Sicherheitsgründen einen leeren String. NurdataTransfer.typesunditems(Art/Typ) sind lesbar; die Daten stehen erst imdrop-Handler bereit. dropEffectmuss zu dem indragstartgesetzteneffectAllowedpassen, sonst wird das Ablegen trotzdem abgelehnt.- Wird eine Datei außerhalb der Ablagezone losgelassen, öffnet der Browser sie standardmäßig. Ggf. auf
windowdragoverunddropmitpreventDefault()abfangen. - Kompatibilität: In allen Desktop-Browsern unterstützt. Auf Touch-Geräten ist HTML-Drag-and-Drop eingeschränkt (iOS Safari erst ab Version 15 vollständig); für mobile Oberflächen Pointer Events als Alternative erwägen.
- Die
target-Eigenschaft zeigt oft auf Kindelemente; für stabiles Verhaltenclosest()odercurrentTargetverwenden.