Start · Sprachen · JavaScript · Referenz · HTMLElement: drag

HTMLElement: drag

Ereignis

Wird während eines Ziehvorgangs wiederholt (etwa alle paar hundert Millisekunden) am gezogenen Element bzw. an der gezogenen Textauswahl ausgelöst.

seit JavaScript Baseline: alle Browser (HTML Drag and Drop API) Kategorie: webapi

Signatur

element.addEventListener("drag", handler)

Beschreibung

Das drag-Ereignis gehört zur HTML-Drag-and-Drop-API. Es feuert am Quellelement, also am Element, das gezogen wird. Das passiert fortlaufend, solange der Benutzer zieht: typischerweise alle 50–350 ms, auch wenn sich die Maus gerade nicht bewegt. Damit das Ereignis bei beliebigen Elementen auftritt, müssen sie mit draggable="true" ziehbar gemacht werden. Links, Bilder und Textauswahlen sind von Haus aus ziehbar.

Einen Listener registrierst du entweder mit element.addEventListener("drag", handler) oder über die Eigenschaft element.ondrag = handler. Der Handler bekommt ein DragEvent. Das Ereignis steigt auf (bubbles), deshalb eignet es sich gut für Event-Delegation auf einem gemeinsamen Elternelement oder auf document. Es lässt sich abbrechen: preventDefault() bricht in manchen Browsern den Ziehvorgang ab, das ist aber nicht einheitlich umgesetzt.

Typische Einsatzfälle sind visuelles Feedback während des Ziehens (zum Beispiel das Quellelement abdunkeln), das Mitschreiben der Zeigerposition über clientX/clientY oder Auto-Scrolling, wenn der Zeiger den Rand eines Containers erreicht. Der Ablauf der Ereignisse ist: dragstart → wiederholt drag (dazu am Ziel dragenter/dragover/dragleave) → drop am Ziel → dragend an der Quelle.

Parameter

Name Typ Default Beschreibung
$type Pflicht string Der Ereignisname "drag".
$handler Pflicht (event: DragEvent) => void Callback, der bei jedem drag-Ereignis aufgerufen wird. Er erhält ein DragEvent mit dataTransfer, clientX, clientY und weiteren Eigenschaften.
$options boolean | AddEventListenerOptions false Optionen wie capture, once, passive oder signal (zum Entfernen per AbortController).

Rückgabewert

Typ
void
Beschreibung
addEventListener gibt nichts zurück. Der Handler erhält ein DragEvent (erbt von MouseEvent). Das Ereignis steigt auf, ist abbrechbar und hat keine Standardaktion, die man gezielt verhindern müsste.

Beispiele

Quellelement während des Ziehens hervorheben

// HTML: <div id="karte" draggable="true">Zieh mich</div>
const karte = document.querySelector('#karte');

karte.addEventListener('dragstart', (e) => {
  e.dataTransfer.setData('text/plain', karte.id);
});

karte.addEventListener('drag', () => {
  // Wird wiederholt ausgelöst – nur Klasse setzen, keine teure Logik
  karte.classList.add('wird-gezogen');
});

karte.addEventListener('dragend', () => {
  karte.classList.remove('wird-gezogen');
});

Zeigerposition gedrosselt protokollieren

const quelle = document.querySelector('[draggable="true"]');
let letzterLog = 0;

quelle.addEventListener('drag', (e) => {
  const jetzt = performance.now();
  if (jetzt - letzterLog < 200) return; // höchstens alle 200 ms
  letzterLog = jetzt;
  // Achtung: Firefox liefert hier 0/0
  console.log(`Position: ${e.clientX}, ${e.clientY}`);
});
Position: 312, 148 Position: 340, 162

Auto-Scroll am Containerrand per Delegation

const liste = document.querySelector('#liste');
const RAND = 40;

liste.addEventListener('drag', (e) => {
  if (e.clientY === 0) return; // Ende des Ziehvorgangs bzw. Firefox
  const { top, bottom } = liste.getBoundingClientRect();
  if (e.clientY < top + RAND) liste.scrollBy(0, -10);
  else if (e.clientY > bottom - RAND) liste.scrollBy(0, 10);
});

on-Property nutzen und Listener wieder entfernen

const el = document.querySelector('#karte');

// Variante 1: on-Property (nur ein Handler möglich)
el.ondrag = (e) => console.log('zieht…', e.type);
el.ondrag = null; // wieder entfernen

// Variante 2: removeEventListener mit derselben Funktionsreferenz
const beimZiehen = () => console.log('zieht…');
el.addEventListener('drag', beimZiehen);
el.addEventListener('dragend', () => {
  el.removeEventListener('drag', beimZiehen);
}, { once: true });
zieht…

// Wichtig · Fallstricke

  • Hohe Auslösefrequenz: drag feuert ständig. Halte den Handler schlank, drossle ihn bei Bedarf oder bündle DOM-Änderungen mit requestAnimationFrame.
  • Koordinaten in Firefox: Firefox liefert bei drag für clientX/clientY/screenX seit Langem 0 (Bug 505521). Als Ausweg liest man die Koordinaten aus dragover auf document. Auch Chromium meldet beim letzten drag vor dragend oft 0,0.
  • Kein Zugriff auf Daten: Während drag ist dataTransfer im geschützten Modus, getData() gibt also einen leeren String zurück. Daten setzt man in dragstart und liest sie in drop.
  • Nicht das Ziel: drag tritt nur an der Quelle auf. Für Ablageziele sind dragover (mit preventDefault()) und drop zuständig.
  • Touch-Geräte: Auf Mobilgeräten wird die native Drag-and-Drop-API erst seit Kurzem und nur eingeschränkt unterstützt (iOS Safari ab 15, Android Chrome je nach Version). Für zuverlässige Touch-Bedienung sind Pointer Events meist die bessere Wahl.
  • Dateien, die von außerhalb des Browsers hereingezogen werden, lösen kein drag aus, weil die Quelle nicht im Dokument liegt.