Drag-und-Drop ohne Javascript und CSS - so geht's
Vor HTML5 hat Drag-und-Drop nur mit einer Mischung aus Javascript und CSS funktioniert. Dank HTML 5 können Sie diesen Effekt direkt mit HTML implementieren. Im Workshop erfahren Sie, was Sie dabei beachten sollten.

Javascript-Bibliotheken wie jQuery oder Mootools bieten Ihnen heute verschiedene Drag-und-Drop-Effekte an, die Sie ohne größeren Aufwand implementieren können. Dank HTML5 wird dies mit den neuen Browser-Generationen noch einfacher. Die neue Drag-und-Drop-API kennt insgesamt sieben Ereignisse, die...
Javascript-Bibliotheken wie jQuery oder Mootools bieten Ihnen heute verschiedene Drag-und-Drop-Effekte an, die Sie ohne größeren Aufwand implementieren können. Dank HTML5 wird dies mit den neuen Browser-Generationen noch einfacher. Die neue Drag-und-Drop-API kennt insgesamt sieben Ereignisse, die ein Objekt auslösen kann. Dazu kommt noch die Eigenschaft draggable, mit der ein HTML-Element innerhalb des Browsers verschiebbar wird.
Ein erstes Beispiel
In einem ersten Beispiel zeigen wir, wie Sie ein Bild von einem Rahmen in einen anderen bewegen können. Für diese Vorgehensweise gibt es mehrere Ereignisse, die Sie abfangen und verarbeiten müssen.

Damit Sie das Bild von einem Ort zum anderen bewegen können, müssen Sie diesem als Erstes die Eigenschaft draggable des Bilds auf true setzen. Damit können Sie es jedoch noch nicht am Zielort platzieren.
Dazu müssen Sie mehrere Aktionen definieren: was mit dem Objekt passiert, wenn Sie beginnen, es zu bewegen, und was, wenn Sie damit wieder aufhören. Den Start der Bewegung fangen Sie über das Ereignis ondragstart() ab. Dieses löst in unserem Beispiel die Funktion starte_bewegung aus, die festlegt, welches Objekt verschoben werden soll.
Ratgeber: HTML5 - Quick Reference Guide
Für diese Aktion benötigen Sie noch eine Reihe weiterer Daten, die Sie über die Methode set-Data() festlegen. Zum Bewegen eines Objektes benötigen Sie zumindest zwei Daten: den Datentyp des Objektes sowie den Wert. Beides legen Sie in der Methode als Parameter fest.
ev.dataTransfer.setData("Text",ev.
target.id);
In unserem Beispiel übergeben wir für das Objekt "Text" als Datentyp und die ID des Objektes, also drag1, als Wert.
Landezone und Landung
Wenn Sie mit diesen Informationen Ihre Website erneut aufrufen, sind keine Änderungen sichtbar. Das Bild lässt sich zwar bewegen, jedoch gibt es keinen Ort außer dem Startpunkt, wohin es verschoben werden kann. Dafür sind zwei weitere Festlegungen notwendig: die zulässige Landezone, in welcher Sie das Objekt platzieren können sowie die Schritte, die für eine Landung relevant sind.
Für unser Beispiel definieren wir eine explizite Landezone, in welcher Sie das Objekt platzieren können. Diese Festlegung geschieht über ein weiteres div-Tag, das auf die Ereignisse ondrop und ondragover reagiert.
<div id="div2" ondrop="beende_
Bewegung(event)" ondragover="Drop_
erlaubt(event)"></div>
Wenn Sie ein Objekt über den Bildschirm bewegen, ist es im Standard nicht möglich, dieses an einer beliebigen Stelle auf einem anderen Objekt zu platzieren. Damit dies trotzdem funktioniert, müssen Sie diese Standardfunktion einfach abstellen. Dazu steht Ihnen die Methode prevent- Default() des auslösenden Ereignisses zur Verfügung.
ev.preventDefault();

Rufen Sie anschließend die Website wieder auf, verändert sich zwar der Cursor über dem Landebereich, das Bild lässt sich aber immer noch nicht an der Stelle platzieren. Dazu fehlt noch ein weiterer Schritt, der beschreibt, was am Ende der Bewegung getan werden soll.
Diesen verknüpfen Sie mit dem Ereignis ondrop() des div-Tags und hinterlegen die Funktion beende_Bewegung(). Diese führt insgesamt drei Aktionen aus:
- Im ersten Schritt deaktivieren Sie die Standardaktion, die der Browser ausführen würde. Bei einem drop-Ereignis ist dies das Öffnen eines Links im Browserfenster.
- Als Nächstes werden die Daten, welche abgelegt wurden, ermittelt. Dazu wird eine Variable data definiert und dieser die übermittelten Daten aus dem Ereignis mit der getData()-Methode zugewiesen.
- Im letzten Schritt wird das bewegte Element mit dem Zielcontainer verknüpft. Dazu ermitteln Sie über document.getElement ById(data) die ID des bewegten Elements, also drag1. Dieses verknüpfen Sie über die Methode target.appendChild() mit Ihrem Zielobjekt.
Optimierungen und Layout
Wenn Sie das Objekt auch wieder auf seinen Ausgangspunkt zurück bewegen möchten, ist noch eine Ergänzung notwendig. Dazu definieren Sie um das Image-Tag herum ein zweites div-Tag, welches in gleicher Art und Weise auf die Ereignisse ondrop() und ondragover() reagiert. Damit können Sie das Bild beliebig von dem linken in den rechten Container verschieben.
<div id="div1"
ondrop="beende_
Bewegung(event)"
ondragover="Drop_
erlaubt(event)"><img src="qualle.jpg"
draggable="true" ondragstart="starte_
Bewegung(event)" id="drag1"
width="200" /></div>
Mit diesen Anpassungen besitzen sowohl das Bild als auch der umgebende Container jeweils die notwendigen Ereignisse, damit ein Beenden der Bewegung und eine Platzierung des Bildes möglich sind.
Ratgeber: HTML5-Tipps für mobile Geräte
Damit die beiden Bereiche auch als Kästen erkennbar sind, wird noch ein wenig CSS verwendet. Für die Definition nutzen Sie einfach die beiden div-Tags und versehen diese mit den notwendigen Eigenschaften.
#div1, #div2 {
float:left;
width:200px;
height:150px;
margin:10px;
padding:10px;
border:1px solid black;
}
Die Breite und die Höhe sollten Sie an die Bemaßung Ihrer Grafik anpassen, für den Rest sind keine zwingenden Änderungen notwendig, solange Sie die Position der beiden Bereiche nicht verändern möchten.
Die Eigenschaft dataTransfer
Eine zentrale Eigenschaft, die beim Starten und Beenden einer Bewegung zum Einsatz kommt, ist dataTransfer. In unserem Beispiel kommt sie mit den beiden Attributen setData() und getData() zum Einsatz. Zu Beginn der Bewegung wird der Inhalt des Objektes bestimmt, also in unserem Fall die ID des Bildes, die als Daten weitergegeben werden sollen. Da es sich dabei um eine Zeichenkette handelt, nutzen wir hierfür den Datentyp "Text".
Diese Informationen sind wieder notwendig, wenn Sie die Bewegung beenden möchten. Zu diesem Zeitpunkt lesen Sie den am Ereignis hinterlegten Wert wieder über die Methode getData() aus und erhalten die ID des Bildes wieder als Rückgabewert.
Darüber hinaus bietet Ihnen dataTransfer noch eine Reihe von weiteren Eigenschaften. Die wichtigsten im Zusammenspiel mit dem Drag-und-Drop-Effekt sind effectAllowed(), dropEffect() und setDragImage().
Die erste Eigenschaft effectAllowed() legt fest, welche Operationen für den Drag-Vorgang erlaubt sind. Dieser Wert ist während des dragstart()-Ereignisses änderbar und kann die folgenden Werte haben: none, copy, copyLink, copyMove, link, linkMove, move, all, uninitialized.
dropEffect() spiegelt im Aussehen des Cursors wieder, um welche Art von Bewegung des Objektes es sich handelt. Es stehen Ihnen die Alternativen none, move, copy und link zur Verfügung.
Damit bestehen für die Drag-und-Drop-Operation zwei Abhängigkeiten: Zum einen gibt effectAllowed() an, welche Aktion generell zur Verfügung steht. dropEffect() regelt darüber hinaus den aktuellen Typ der Aktion - ist diese jedoch nicht bereits durch effectAllowed() vorgesehen, dann kann das Objekt nicht am Zielort platziert werden.
Wenn Sie planen, diese beiden Eigenschaften zu nutzen, dann sollten Sie die folgende Vorgehensweise verfolgen:
- Legen Sie die erlaubten Aktionen zum Start der Drag-Aktion in einem Handler fest, welcher das ondragstart-Ereignis überwacht und die entsprechenden Aktionen definiert.
- Es ist möglich, für jedes Objekt separate Aktionen festzulegen, welche zulässig sind. Dies regeln Sie über die Eigenschaft dropEffect.
- Legen Sie kein dropEffect für ein Objekt fest, wird dies Eigenschaft ausschließlich über die Festlegungen in effectAllowed beeinflusst.
dragStart = function(ev) {
ev.dataTransfer.effectAllowed = move;
ev.dataTransfer.dropEffect = move;
};
Im Beispiel wird übergreifend als erlaubter Effekt nur move festgelegt. Da Sie die Auswahl auf einen Wert beschränken, ist eine weitere Definition von dropEffect in diesem Fall nicht zwingend notwendig.
Weitere Optimierungen

Es gibt noch eine Reihe von optischen Effekten, die Sie dem Drag-und-Drop-Ereignis hinzufügen können. Eines davon ist die Anpassung des Mauszeigers während des Ziehens Ihres Objektes. Im folgenden Beispiel fügen Sie zum Mauszeiger ein zusätzliches Icon hinzu, welches jedoch nur während des Vorgangs angezeigt wird und nach dem Beenden der Bewegung wieder verschwindet.
Dazu erweitern Sie die Funktion starte_Bewegung() entsprechend.
function starte_Bewegung(ev){
var dragIcon = document.
createElement('img');
dragIcon.src = 'icon.png';
ev.dataTransfer.setData("Text",ev.
target.id);
ev.dataTransfer.
setDragImage(dragIcon, -10, -10);
}
In der ersten Zeile wird eine neue Variable definiert, welche den Zugriff auf ein neu angelegtes Image-Objekt erlaubt. Dieses Image-Objekt wird mit einem lokal abgelegten Symbol mit dem Namen icon.png verknüpft. Dieses Symbol wird während der Ausführung der Bewegung entsprechend angezeigt.
Damit dies auch wirklich passiert, ist noch die Verknüpfung des Symbols mit der Ziehbewegung notwendig. Dies realisieren Sie über die Eigenschaft setDragImage, der Sie neben dem Verweis auf die Image-Datei auch deren Position mitgeben. In unserem Beispiel ist dies rechts unterhalb des Mauscursors, was durch die beiden Koordinaten -10 für die x- und y-Achse beschrieben wird.
Bild in Text umwandeln
Mit HTML5-Drag-und-Drop lässt sich jedoch nicht nur das Ziehen eines Objektes von einem Ort zum anderen realisieren, Sie können damit auch verschiedene Objekte beispielsweise in einen Warenkorb ziehen und anschließend dort die Inhalte anzeigen. Dazu platzieren wir drei Bilder auf der Website und legen eine definierte Landezone fest. Das bisherige Beispiel benötigt für diesen Fall nur geringfügige Veränderungen. Die Funktionen Drop_erlaubt() und beende_Funktion() bleiben erhalten, wie sie sind, die Funktion starte_Bewegung() wird auf ihren Urzustand zurückgebaut, wie im Listing links beschrieben.
Die wesentlichen Änderungen passieren im body-Bereich der HTML-Seite sowie anschließend auch bei der CSS-Formatierung.
<body><div id="div1" ondrop="beende_
Bewegung(event)" ondragover="Drop_erlaubt(event)"></div><img src="tulpe.jpg" draggable="true"
ondragstart="starte_Bewegung(event)" id="tulpe" width="200" /><img src="Chrysantheme.jpg"
draggable="true" ondragstart="starte_Bewegung(event)" id="chrysantheme" width="200" /><img src="Hortensie.jpg"
draggable="true" ondragstart="starte_Bewegung(event)" id="hortensie" width="200" /></body>
Der body-Bereich enthält jetzt drei Grafiken, die alle beweglich sind und beim Auslösen des Ereignisses ondragstart die Funktion starte_Bewegung() aufrufen.
Für die Simulation des Warenkorbs benötigen wir nur noch eine markierte Zone, in der die Bilder platziert werden sollen. Diese wird mit einem div-Element gekennzeichnet und wieder mit den bekannten Event-Handlern für ondrop und ondragover versehen.
Einige Anpassungen sind auch bei der Formatierung des div-Bereichs div1 geschehen. Dieser ist jetzt größer und kann somit auch problemlos alle drei Bilder aufnehmen.
#div1 {
width:500px;
height:350px;
margin:10px;
padding:10px;
border:3px solid black;
}
Wenn Sie diesen Programmcode ausführen, haben Sie einen Warenkorb vor sich, in den Sie alle drei Elemente ziehen können. Diese werden dann auch alle gleichzeitig an dieser Stelle angezeigt.
Unterstützung in Browsern
Die Definition von HTML5 ist noch immer nicht vollständig verabschiedet, die Browserhersteller sind jedoch bereits recht weit vorangeschritten bei der Implementierung des vorläufigen Standards. In den aktuellen Versionen gibt es bei der HTML5-Umsetzung für Drag-und-Drop nur noch wenige kleine Lücken.
Anders sieht es jedoch bei älteren Browserversionen aus. Sollten Sie also primär auf eine Umsetzung in HTML5 bauen, sollten Sie trotz allem eine alternative Lösung anbieten. Eine optimale Weiche für die Entscheidung, ob der eingesetzte Browser die notwendigen Funktionen unterstützt, liefert beispielsweise das Framework Mordernizr (modernizr.com ).
Listing: Das bewegte Bild
<html><head><style type="text/css">
#div1, #div2 {
float:left;
width:200px;
height:150px;
margin:10px;
padding:10px;
border:1px solid black;
}</style><script>
function Drop_erlaubt(ev){
ev.preventDefault();
}
function drag(ev){
ev.dataTransfer.setData("Text",ev.target.id);
}
function drop(ev){
ev.preventDefault();
var data=ev.dataTransfer.getData("Text"); ev.target.appendChild(document.getElementById(data));
}</script></head><body><div id="div1" ondrop="drop(event)" ondragover="Drop_erlaubt(event)"><img src="qualle.jpg" draggable="true"ondragstart="drag(event)"
id="drag1" width="200" /></div><div id="div2" ondrop="drop(event)" ondragover="Drop_erlaubt(event)"></div></body></html>