Drag & Drop 2
Ich hatte ja schon ein einfaches Drag & Drop Skript hier vorgestellt, dass aber nicht allen Anforderung gerecht wird. Ich brauchte ein Skript, mit dem man Teile innerhalb eines Bereiches, Dragbar macht. Also das was man von normalen Fenstern kennt, das ganze Fenster läßt sich durch ziehen am Titel bewegen. Ausserdem gab es noch ein kleines Opera Problem, der beim Draggen den Text markierte. All das ist mit diesem Skript gelöst.
Benutzung
Das Skript wird am einfachsten als externe Javascript Datei eingebunden, auf die übliche Weise:
<script type="text/javascript" src="dragObject.js"></script>.
Ein Objekt wird dann Dragbar gemacht, indem nach dem Laden des Elementes (entweder im HTML Quellcode dahinter oder in einem onload Handler) mit:
new DragObject( object1, object2) ein Dragbares Objekt erzeugt wird.
Konkret sieht ein Beispiel so aus:
<div id="test">
<div id="titel">Titel </div>
Box.
</div>
<script type="text/javascript" src="dragObject.js"></script>
<script type="text/javascript">
window.onload = function()
{
new DragObject( document.getElementById('test'), document.getElementById('titel') );
};
</script>
Methoden
- ini(objekt [, objekt])
- Der erste Parameter ist das Objekt, das verschoben werden soll. Der zweite optionale Parameter, ist das Objekt mit dem das erste verschoben werden kann, z.b. die Titelzeile eines Fensters. Ist dieser undefiniert, dann kann ist das ganze Objekt verschiebar.
- setPos(top, left)
- Die Position des Objektes neu setzen.
- getPos()
- Rückgabe ist ein Array mit den Werten:
[top, left, height, width].
- obj()
Events
- onstart(e)
- Der Event, der beim klickenauf ein Drag&Drop Objekt gefeuert wird.
- onmove(e, neu_top, neu_left)
- Event der beim bewegen des Elementes gefeuert wird. Ist der Rückgabewert
falsewird die Bewegung zur neuen Position nicht ausgeführt - ondrop(e)
- Event der beim fallen lassen des Elementes gefeuert wird. Ist der Rückgabewert
false, wird das Element wieder an die ursprüngliche Position gesetzt.
Donwload
Beispiel
In dieser Box ist ein Element, dass nur innerhalb der Box bewegt werden kann. Wird es nach ausserhalb bewegt, wird der Hintergrund der Box rot und beim Droppen wird es dann wieder an die alte Position gesetzt.
Der entscheidende Code dafür sieht folgendermaßen aus:
// erzeugen des DragObjektes. |
var tmp = new DragObject(o, o.childNodes[0] ) |
// Der drag Event |
tmp.ondrag = function(e, top, left){ |
var drag_objekt = this.getPos(); |
// box_top/left/bottom/right sind die Berechneten Werte, der box. |
var is_in = (left >; box_left) && |
(top > box_top) && |
(drag_objekt[2] + top < box_bottom) && |
(drag_objekt[3] + left < box_right); |
box.style.backgroundColor = is_in ? 'white' : 'red'; |
}; |
// Drop Event |
tmp.ondrop = function(e){ |
box.style.backgroundColor = 'white'; |
var drag_objekt = this.getPos(); |
var is_in = (drag_objekt[1] > box_left) && |
(drag_objekt[0] > box_top) && |
(drag_objekt[2] + drag_objekt[0] < box_bottom) && |
(drag_objekt[3] + drag_objekt[1] < box_right) |
// Wenn is_in false ist, |
//wird das DragObjekt wieder an die Ausgangsposition zurück gesetzt |
return is_in; |
}; |
So sieht's aus
Titel

Text unter'm Foto.
9243 mal gelesen.


25 Kommentare Einen Kommentar hinterlassen »
Kommentare
Donnerstag 22.März 2007: 23:50
Klasse tool.
Da ich auf meiner Seite schon Grafiken mit id hatte, konnte ich die alle dragfähig machen. So weit zur Spielerei.
Interessant wäre eine Anwendung, mit der man per drag & drop einfach Datensätze (oder ganze Tabellen) in die Nackup- Datenbank verschiebt.
Mal sehen, wie man dropen kann.
Lieben Gruß, Kalle_B
Mittwoch 18.April 2007: 14:45
Hallo,
habe eben im SelfHTML- Forum die Frage gestellt, warum meine Objekte beim Initialisieren ihre Position verlassen.
Mache die Initialisierung bewusst 3 sec nach onLoad, damit man es sehen kann.
http://forum.de.selfhtml.org/?t=150741&m=979860
Lieben Gruß, Kalle
Mittwoch 20.Juni 2007: 10:57
Hallo,
Klasse script!
Aber wie kann ich zusätzlich noch erreichen das die Gerade verschobenen Elemente 'on top' bleiben (z-index)?
Gruß l8a
Mittwoch 20.Juni 2007: 11:33
Das sollte eigentlich so sein, es denn du hast Elemente mit einem z-index höher als 999
Mittwoch 20.Juni 2007: 14:47
Hallo.
Nein habe ich nicht. Wenn ich es dragge wird der z-index auf 999 gesetzt, sobald ich es jedoch drope wird er auf 0 gesetzt und der layer wird von dem anderem layer, über den ich ihn dropte, der später kreiert wurde überlagert.
Freitag 22.August 2008: 20:32
Hallo Struppi,
etwas verstehe ich immer noch nicht an dem schönen Programm:
1.) Wozu dienen die Funktionen:
this.ondrop = function() {return true;};
this.ondrag = function() {return true;};
this.onstart = function() {return true;};
2.) Wieso kann eine Funktion, die ohne Par.
definiert wird, s.o., mit mehreren Par.
aufgerufen werden?
this.ondrag(e, new_top, new_left)
3.) Es wird in einer Abfrage (Sonderfall)
programmiert:
if(!dragObject) return end_drag(e);
Die Funktion end_drag(e) ist in der
1.Version vorhanden, aber hier fehlt sie.
Viele Grüße Ernesto
Samstag 23.August 2008: 12:06
Ich hab den Artikel mal entsprechend erweitert, vielleicht hilft's ja deine Fragen zu beantworten.
Mittwoch 27.August 2008: 9:43
Hallo Struppi,
entschuldige, daß ich erst jetzt antworte.
Das Script ist super !!! Ich habe bei meinen
Problemen Deine Anregungen und Hilfen gut ge-
brauchen können. Ich habe nicht Dein Script
dazu geladen, weil in meiner Situation noch
andere Umstände eine Rolle spielen: Ich soll
ein Bild u.a. aus einer Übersicht auswählen,
vergrößern, verkleinern, z-Index bestimmen
usw. können. Unter anderem darf ein Bild
nicht aus einem bestimmen Bereich bewegt
werden (siehe oben!). Aber ich habe Deine
Anregungen benutzt, um meine Probleme zu
lösen, mein Script läuft jetzt soweit.
Vielen Dank nochmal dafür!!!
Zusatzfrage:
Kann man ein Bild mit Javascript auch drehen?
Man müßte dann alle Pixel intern verschieben?
Ich denke, es ist auf jeden Fall sehr auf-
wendig.
Viele Grüße
Ernesto
Mittwoch 27.August 2008: 9:48
Nein, das kann man mit JS nicht.
Sonntag 28.September 2008: 18:02
schöne spielerei
vielleicht kann man das mal irgendwo einsetzten
Donnerstag 4.Juni 2009: 19:46
Hallo,
das Script ist wirklich wunderbar.
Ich bräuchte es nur so, dass man 2 Boxen hat, die man bewegt.
Was müsste man da verändern?
Sonntag 7.Juni 2009: 0:28
Du musst einfach die zweite Box mit new DragObject( ...); initialisieren
Montag 8.Juni 2009: 18:34
Ich habe jetzt unter die Variable var obj = ... folgenden Code ergänzt (der Code in den Eckigen Klammer war ja schon):
var obj2 = document.getElementById('dragObjekt2');
[ var tmp = new DragObject(obj, obj.childNodes[0] ); ]
var tmp = new DragObject(obj2, obj2.childNodes[0] );
Damit kann ich jetzt beide Boxen bewegen, aber es wir leider nicht die Funktion ausgeführt, dass beide Boxen daraufhin überprüft werden, ob sie nun im Feld sind oder nicht, das geschieht nur bei der ersten.
Montag 8.Juni 2009: 18:42
Die Eventhandler in dem Beispiel oben, musst du jedem Objekt zuweisen
var tmp = new DragObject(obj, obj.childNodes[0] );
var tmp2 = new DragObject(obj2, obj2.childNodes[0] );
tmp.ondrag = tmp2.ondrag = function(e, top, left){ ....}
Montag 8.Juni 2009: 20:26
Ja, jetzt klappt es besser, aber die Funktion tmp.ondrag wird für das zweite Element nicht ausgeführt.
Ich habe, um einen besseren Überblick zu behalten, mal alle Funktionen gedoppelt, d.h. für ondrag() hab ich einmal tmp.ondrag und tmp2.ondrag bei den anderen auch.
Es macht aber gar keinen Unterschied, ob ich nun tmp2.ondrag im Script habe, oder es ausklammere...
Wenn du dir mal die Dateien anschauen willst: [Link entfernt]
Trotzdem schon mal vielen Dank!
Montag 8.Juni 2009: 23:00
Der Link bringt mir nichts, zumal nicht bei einem offensichtlich kostenpflichtigen Filesharing Angebot, das zu dem meine Fenstergröße ändert, das hab ich gleich wieder zu gemacht. Ich werde den Link entfernen
Samstag 11.Juli 2009: 22:13
Wenn du alles doublest, gehts!
//var Drag = DragObject;
function getPos(o) {
for(var top = o.offsetTop, left = o.offsetLeft; o = o.offsetParent; top += o.offsetTop, left += o.offsetLeft) {}
return [top, left];
}
window.onload = function()
{
var box = document.getElementById('test');
var box_top = getPos(box)[0];
var box_left = getPos(box)[1];
var box_bottom = box.offsetHeight + box_top;
var box_right = box.offsetWidth + box_left;
var obj = document.getElementById('dragObjekt');
var obj2 = document.getElementById('dragObjekt2');
var tmp = new DragObject(obj, obj.childNodes[0] );
var tmp2 = new DragObject(obj2, obj2.childNodes[0] );
tmp.ondrag = function(e, top, left){
var drag_objekt = this.getPos();
var is_in = (left > box_left) &&
(top > box_top) &&
(drag_objekt[2] + top < box_bottom) &&
(drag_objekt[3] + left box_left) &&
(top > box_top) &&
(drag_objekt[2] + top < box_bottom) &&
(drag_objekt[3] + left box_left) &&
(drag_objekt[0] > box_top) &&
(drag_objekt[2] + drag_objekt[0] < box_bottom) &&
(drag_objekt[3] + drag_objekt[1] box_left) &&
(drag_objekt[0] > box_top) &&
(drag_objekt[2] + drag_objekt[0] < box_bottom) &&
(drag_objekt[3] + drag_objekt[1] < box_right);
return is_in;
};
};
Samstag 11.Juli 2009: 22:15
Also so:
//var Drag = DragObject; function getPos(o) { for(var top = o.offsetTop, left = o.offsetLeft; o = o.offsetParent; top += o.offsetTop, left += o.offsetLeft) {} return [top, left]; } window.onload = function() { var box = document.getElementById('test'); var box_top = getPos(box)[0]; var box_left = getPos(box)[1]; var box_bottom = box.offsetHeight + box_top; var box_right = box.offsetWidth + box_left; var obj = document.getElementById('dragObjekt'); var obj2 = document.getElementById('dragObjekt2'); var tmp = new DragObject(obj, obj.childNodes[0] ); var tmp2 = new DragObject(obj2, obj2.childNodes[0] ); tmp.ondrag =tmp2.ondrag = function(e, top, left){ var drag_objekt = this.getPos(); var is_in = (left > box_left) && (top > box_top) && (drag_objekt[2] + top < box_bottom) && (drag_objekt[3] + left box_left) && (drag_objekt[0] > box_top) && (drag_objekt[2] + drag_objekt[0] < box_bottom) && (drag_objekt[3] + drag_objekt[1] < box_right); return is_in; }; };Donnerstag 5.November 2009: 20:28
So was habe ich gesucht ... Danke
Frage zum Beispiel:
wenn ich deinen #test -div in einen anderen -div packe und den test-div mit css
position:absolute;
left: 100px;
top: 50px;
positioniere
und das dragObjekt auch
#dragObjekt{position:absolute;
left: 50px;
top: 75px;
border:1px solid black;
}
sieht ja anfangs noch schön aus, aber sobald ich das dragObjekt anklicke verschiebt es sich und der test-div ist auch nicht mehr der "Rahnen" ( Farbwechsel )...
das liegt bestimmt an "position:absolute; und left: xxx; top:xxx; "
was muß man ändern damit die Koordinaten und der Farbwechsel wieder stimmen ?
Ist die Erklärung schlecht ?
hier liegt das geänderte Bsp.
http://www.creativetextilart.de/test/test.Bilder.bewegen3.htm
Freitag 6.November 2009: 11:02
Das Skript ist bewußt schlank und schnell gehalten, die Funktion zur Positionsermittlung prüft nicht alle Sonderfälle, wie z.b. ineinander verschachtelte absolut positionierte Elemente. Ich hab' sie aber mal angepaßt.
Freitag 6.November 2009: 12:12
mit start_pos ... und so schnell, du bist richtig gut.
was muss noch geändert werden, damit auch der Farbwechsel wie in deinem Bsp. bei mir fkt. ?
Danke für deine Hilfe.
Freitag 6.November 2009: 12:56
Meine Empfehlung: verzichte auf ineinander verschachtelte absolut positionierte Elemente. So ist es zu kompliziert das Element mit JS zu positionieren.
Freitag 6.November 2009: 16:01
ich möchte ein solches Layout erzeugen:
http://www.creativetextilart.de/test/tabelle.gif
erst hatte ich Tabellen, die haben aber je nach Inhalt ihre Größe geändert ( trotz fester Höhe/Breite Angaben)
dann habe ich auf div' mit css umgestellt, um das Layout umzusetzen. habe ich nur mit position:absolute hin bekommen. In den 400/400 Block in der Mitte soll dann noch der Test von oben.
Gibt es eine andere Mgl. mein gewünschtes Layout ohne position:absolute hinzubekommen und so dein drag/drop mit einbinden zu können ?
Sonntag 18.Juli 2010: 14:52
Hallo,
ist wirklich ein tolles Script. Gibt es auch eine Möglichkeit das wenn man das Element verschoben hat, dieses beim nächsten Aufruf oder beim aktualisieren der Seite an der Position erscheint wohin man es verschoben hat?.
Gruß,
bioweg
Mittwoch 21.Juli 2010: 9:05
Die Möglichkeit gibt es. Die einfachste wäre, diese Werte in einem Cookie zu speichern.
Einen Kommentar hinterlassen