Javascript ist Toll!

14. February 2007 - 13:11

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, weil der beim Draggen den Text markierte.

Benutzung

Das Skript wird als externe Javascript Datei eingebunden. Zum Beipsiel auf die übliche Weise:
<script type="text/javascript" src="dragObject.js"></script>.

Ein Objekt wird dann dragbar gemacht, indem nach dem Laden des Elements (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 wird das Obejkt im ersten Parameter als zum Draggen benutzt.
setPos(top, left)
Das Element positionieren.
getPos()
Rückgabe der Positionen, als ein Array mit den Werten: [top, left, height, width]
obj()
Das Dragobjekt

Events

onstart(e)
Der Event, der beim klick auf ein Drag&Drop Objekt gefeuert wird.
onmove(e, neu_top, neu_left)
Event, der beim bewegen des Elements gefeuert wird. Ist der Rückgabewert false wird die Bewegung zur neuen Position nicht ausgeführt
ondrop(e)
Event der beim droppen des Elements gefeuert wird. Ist der Rückgabewert false, wird das Element wieder an die ursprüngliche Position gesetzt.

Donwload

dragObject.js

Beispiel

In dieser Box ist ein Element, dass nur innerhalb der Box bewegt werden kann. Wird es nach ausserhalb bewegt, färbt sich der Hintergrund der Box rot und beim Droppen wird das Element wieder an die alte Position gesetzt.

Der 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 berechnete Werte der äußeren 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.

ähnliche Artikel

Comments (38)
2106 mal gelesen.

38 Kommentare

Leave a comment »

Seiten:

1. Comment von: Kalle_B
22. March 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

2. Comment von: Kalle_B
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

3. Comment von: l8a
20. June 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

4. Comment von: Struppi
20. June 2007: 11:33

Das sollte eigentlich so sein, es denn du hast Elemente mit einem z-index höher als 999

5. Comment von: l8a
20. June 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.

6. Comment von: Ernesto
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 :-)

7. Comment von: Struppi
23. August 2008: 12:06

Ich hab den Artikel mal entsprechend erweitert, vielleicht hilft’s ja deine Fragen zu beantworten.

8. Comment von: Ernesto
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

9. Comment von: Struppi
27. August 2008: 9:48

Nein, das kann man mit JS nicht.

10. Comment von: Dietmar
28. September 2008: 18:02

schöne spielerei ;)
vielleicht kann man das mal irgendwo einsetzten

11. Comment von: Borsti93
4. June 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?

12. Comment von: Struppi
7. June 2009: 0:28

Du musst einfach die zweite Box mit new DragObject( …); initialisieren

13. Comment von: Borsti93
8. June 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.

14. Comment von: Struppi
8. June 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){ ….}

15. Comment von: Borsti93
8. June 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! :D

16. Comment von: Struppi
8. June 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

17. Comment von: Fabian
11. July 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;
};
};

18. Comment von: Fabian
11. July 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 &gt; box_left) &amp;&amp;
		(top &gt; box_top) &amp;&amp; 
		(drag_objekt[2] + top &lt; box_bottom) &amp;&amp;
		(drag_objekt[3] + left  box_left) &amp;&amp;
		(drag_objekt[0] &gt; box_top) &amp;&amp;
		(drag_objekt[2] + drag_objekt[0] &lt; box_bottom) &amp;&amp;
		(drag_objekt[3] + drag_objekt[1] &lt; box_right);
 
		return is_in;
	};
 
};
19. Comment von: schlaubi666
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

20. Comment von: Struppi
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.

21. Comment von: schlaubi666
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.

22. Comment von: Struppi
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.

23. Comment von: schlaubi666
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 ?

24. Comment von: bioweg
18. July 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

25. Comment von: Struppi
21. July 2010: 9:05

Die Möglichkeit gibt es. Die einfachste wäre, diese Werte in einem Cookie zu speichern.

26. Comment von: Aaron K.
28. August 2010: 12:03

Werde ich nutzen auf meiner HabboFanseite. Vielleicht eher als Spielerei.
Wobei es auch sinnvoll ist, wenn man viele Boxen hat und den Leuten die Möglichkeit geben möchte diese nach wichtigkeit zu ordnen.

Meine Seite ist hässlich und nutzt kein XHTML… aber sau viel JS (von den netten ToolTips über das hier bis zu alert) :D

27. Comment von: Sammy
27. October 2011: 23:11

Hallo,

ist es möglich, das Drag verhalten automatisch per funktionsaufruf zu starten?

Ich möchte, wenn der User auf einen Knopf drückt, ein img Objekt erstellen welches dann gleich sozusagen am Cursor “klebt” ohne dass er nochmals drauf klicken muss.

Ansonsten echt tolles Script. Hut ab.

28. Comment von: welle
6. December 2011: 23:54

Hallo Struppi,
das Script läuft super, alle Achtung!
Nur ein kleines Problem, welches ich bis jetzt nicht lösen konnte:
bei einem DIV-Element mit css-style “overflow=auto” lässt es das DragObject nach dem Scrollen
der DIV nicht mehr los.
Das passiert nur beim IE9, bei Firefox nicht.
Habe da schon einiges rumprobiert- leider erfolglos.
Wäre schön, wenn du da eine Idee dazu hättest.

29. Comment von: Struppi
20. December 2011: 11:39

Tut mir leid. Da ich mittlerweile keinen IE mehr habe (nur noch auf einem alten Rechner, einen IE 6) kann ich das nicht testen. Gibt es denn eine Fehlermeldung?

30. Comment von: welle
6. January 2012: 10:39

Nein, keine Fehlermeldung. Es scheint so, dass beim IE die Scroll-Leiste (die ja bei overflow:auto) eingeblendet wird, kein Mouseup-Event empfängt- und auch nicht an das parentNode-Element weiterleitet. Ich werde das Problem wohl so lösen müssen,dass das DragObject-Script die rechten und unteren zwanzig Pixel des Div-Elements nicht mit einbezieht.
Trotzdem danke für die Antwort.

31. Comment von: Sebastian
17. January 2012: 10:18

Hallo,

da ich neu in Javascript bin, ist einiges davon noch sehr unverständlich. Habe Grundlagen in PHP, Java und diversen anderen Sprachen.
Das Script sieht wirklich sehr interessant aus und da ich derzeit ein Projekt vor der Brust habe wo es um Ticketsysteme geht, wäre so etwas natürlich super. Ein Admin könnte die verschiedenen offenen Tickets per Drag an Drop aus dem Feld “offene Tickets” verschiedene Felder zuweisen, welche unterschieldichen Mitarbeitern entsprechen. Ich denke zumindest das soetwas fast möglich mit dem Script wäre^^.

An dieser Stelle:
var tmp = new DragObject(o, o.childNodes[0] )
habe ich ein Bömisches Dorf gefunden^^

Also laut Quelltext kommen die o’s von document.getElementById(‘dragObject’) und dragObject ist die id von einer div in der sich die Überschrift Titel, ein Bild und ein Absatz befindet.
Mit childnodes erhällt man den titel für das Dragobjekt. Aber an fordersterstelle übergibt man das ganze von DragObject. Müsste der Title nicht zweimal auftauchen?

Und noch eine Frage, auch wenn man jetzt denken oh man anfänger. Ich kann doch in mein script ein ondoubleclick einfügen oder. So könnte ich mir nähere Infos zum Ticket geben lassen^^. Wäre super wenn das alles so funktoniert wie ich mir das vorstelle.

Freundliche Grüße
Sebastian

32. Comment von: Struppi
18. January 2012: 23:23

Es müßte eigentlich problemlos möglich sein, einen anderen Event einzubauen.

Die Parameter für den Konstruktor sind, einmal das Objekt das bewegt wird beim draggen und dann optional ein Element auf dem der Dragvorgang gestartet wird. Wie z.b. eine Titelzeile in einem Fenster. Das childNodes Objekt habe ich hier benutzt, weil das Element (die Überschrift) das erste Element ist. Aber es kann auch stattdessen mit getElementById() oder einer ähnlichne Funktion das Element übergeben werden.

33. Comment von: Rehoy
27. July 2012: 20:31

Guten Abend,

ich freue mich, dass ich das Script hier gefunden habe. So wie vorgegeben läuft es super und ich suchte auch schon nach so einer Art. Weiter vorn wurde schon einmal angefragt wie denn die Lösung für zwei zu draggende Objekte sei. Ich probiere schon den ganzen Tag…die Lösung von Fabian funktioniert leider nicht und auch meine eigenen Überlegungen wollen einfach nicht zum Ziel führen. Problem auch dies hier “drag_objekt[2]”. Auf was greife ich hier zu?

Vll nochmal als Nebeninformation was ich überhaupt machen will. Ich möchte einen Test für Schüler programmieren. Dort sollen die zu draggenden DIV-Boxen fest positionierten Boxen richtig zugeordnet werden.

Ich hoffe, ihr könnt mir ein wenig helfen und vielen Dank für eure Hilfe im Voraus.
In diesem Sinne wünsche ich allen noch einen schönen Abend.

34. Comment von: welle
31. July 2012: 18:03

Hallo Rehoy,
ich würde (ungetestet) Folgendes versuchen:

var o=[div1,div2,div3]; (soviele Elemente wie nötig)

for(var i=0;i<o.length;i++){

var tmp = new DragObject(o[i], o[0].childNodes[0] ) ;

}

Theoretisch sollten sich dann alle Divs nach div1.childNodes[0] mitbewegen.

Gruß welle

35. Comment von: welle
31. July 2012: 20:51

Tja- Theorie und Praxis.
Mit meiner Methode kann immer nur EIN Element bewegt werden.
Da muss man wohl die ganze Function umkrempeln, dass mit “new” wirklich ein neues Object ‘DragObject’
erstellt wird.

36. Comment von: welle
31. July 2012: 22:04

Das ließ mir jetzt doch keine Ruhe. :-)
Also hier eine getestete Vorgehensweise.
Man nehme einen zusätzlichen Parameter.
Aufruf dann:

var tmp= new DragObject(object1,object2,testfunction) ;

den Parameter einfügen:
window​.​DragObject​ = ​function​ (​o_move​, ​o_drag​,​ func​​)

in die Function ‘this.setPos’ folgende Zeile einfügen:

if​(​typeof​ ​func​==’​function​’){​​func​(​​l​,​t​​,​move​​)​}​​

nun die function irgendwo im Script einfügen, auf die Bezug genommen werden soll:

function testfunction(x,y,move){
//x= x-Position des Dragobjects, y die y-Position und ‘move’ das Objekt selbst
}
Nun hat man alle Infos, um alle anderen Elemente darauf auszurichten.

Gruß welle

37. Comment von: Rehoy
13. August 2012: 9:01

Sorry für die späte Antwort. Ich habe mir mal ein paar freie Tage gegönnt :-) Vielen lieben Dank für die Hilfe. Ich werde mir das mal zu Gemüte ziehen und ausprobieren.
LG

38. Comment von: Struppi
6. September 2012: 14:40

Mehrere Drag Objekte können einfach mit mehreren new DragObject aufrufen erzeugt werden. Ich seh das Problem nicht.

Ich hab mal ein Beispiel gebastelt: http://javascript.jstruebig.de/js/drag_test2.html
Die beiden gelben Kästchen können nur auf das Kästchen “gedroppt” werden, ansonsten fallen sie immer zur Ausgangsposition zurück.

Leave a comment

Name (required)
Mail (wird nicht angezeigt) (required)
Website

Folgende HTML Tags sind erlaubt: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>



Powered by WordPress Stop Spam Harvesters, Join Project Honey Pot kostenloser Counter Browser-Statistiken
rats-wonderful
rats-wonderful
rats-wonderful
rats-wonderful