• Jetzt anmelden. Es dauert nur 2 Minuten und ist kostenlos!

Drag and Drop

Status
Für weitere Antworten geschlossen.

TAKE OFF

Neues Mitglied
Hallo Community,

erstmal wünsche ich allen ein frohes neues,
und auch im neuen Jahr gibt es wieder Probleme ohne Ende :D

Ich versuche gerade eine Drag und Drop Funktion zu basteln,
dafür schreibe ich mir erstmal eine Event Überwachung,
die die Position von meinen Mauszeiger überwacht (bis hierhin einfach):

Code:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Unbenanntes Dokument</title>
<script type="text/javascript">
   
   function maus_position(ergebnis){
   
      if(!ergebnis){
      
       ergebnis = window.event;
      
      }
      
      wertx = ergebnis.clientX;
      
      werty = ergebnis.clientY;
      
      document.getElementById("ausgabex").innerHTML = wertx;
      
      document.getElementById("ausgabey").innerHTML = werty;
   
   }
document.onmousemove = maus_position;
</script>

</head>

<body>

<table>
<td><b>Weite:</b></td><td id="ausgabex"></td>
<tr>
<td><b>Höhe:</b></td><td id="ausgabey"></td>
</tr>
</table>
</body>
</html>

Um sicherzugehen das alles so klappt wie ich mir das vorstelle,
habe ich mir eine Div Box erstellt, die sich bei gedrückter Maustaste bewegt(auch das funktioniert reibungslos):

Code:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Javascript-Chat</title>

   <script type="text/javascript">
   
      function hover_on(){
      
         document.images[0].src="bilder/button_hover.png";
         document.images[0].style.cursor = "move";
      }
      
      function hover_off(){
      
         document.images[0].src="bilder/button.png";
      
      }
      
      function bewegen(){
      
         document.getElementById("chat").style.top = "300px";
         
         document.getElementById("chat").style.left = "300px";
      
      }

   </script>
   
   <style type="text/css">
   
      .chat_box{
      background:url(bilder/content.png) no-repeat;
      width:517px;
      height:334px;
      position:relative;
      }
   
   </style>
    
</head>

<body>

   <div id="chat" class="chat_box">
   
      <img onmouseover="hover_on()" onmousedown="bewegen()" onmouseout="hover_off()" align="right" src="bilder/button.png" />
   
   </div>

</body>
</html>

Nur das dort noch feste Daten stehen,
meine Idee die festen Daten durch die Daten der Positionsangaben der Maus zu ersetzen,
das ganze sieht dann bei mir so aus:

Code:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Javascript-Chat</title>

   <script type="text/javascript">
   
      function maus_position(ergebnis){
   
         if(!ergebnis){
      
            ergebnis = window.event;
      
         }
      
         wertx = ergebnis.clientX;
      
         werty = ergebnis.clientY;
      
         document.getElementById("ausgabex").innerHTML = wertx;
      
         document.getElementById("ausgabey").innerHTML = werty;
   
      }

      function hover_on(){
      
         document.images[0].src="bilder/button_hover.png";
         document.images[0].style.cursor = "move";
      }
      
      function hover_off(){
      
         document.images[0].src="bilder/button.png";
      
      }
      
      function bewegen(){
      
         document.getElementById("chat").style.top = werty + "px";
         
         document.getElementById("chat").style.left = wertx + "px";
      
      }

   document.onmousemove = maus_position;
   
   </script>
   
   <style type="text/css">
   
      .chat_box{
      background:url(bilder/content.png) no-repeat;
      width:517px;
      height:334px;
      position:relative;
      }
   
   </style>
    
</head>

<body>

   <div id="chat" class="chat_box">
   
      <img onmouseover="hover_on()" onmousedown="bewegen()" onmouseout="hover_off()" align="right" src="bilder/button.png" />
   
   </div>

</body>
</html>

Das ganze geht nur nicht so wie ich das will,
wo habe ich den Fehler gemacht?
Momentan springt bei jedem Mausklick die Box ein bisschen weiter weg ;)

Hier mal das ganze Script mit Bildern zum Download:
Alle Daten -Download-




  • ~TAKE OFF
    Ich bin zu allem bereit, aber zu nichts zu gebrauchen.
 
Wenn ich das richtig verstanden habe, willst du es ein bisschen wie ein Fenster machen.
Habe ich vor kurzem ganz einfach gemacht...

Ich erkläre was du dazu benötigst.

Zu allererst (und das hast du schon, fast) brauchst du eine Funktion, die dir die aktuelle Mausposition zurückgibt. Damit es auch in jedem Browser funktioniert:
PHP:
function getCoords(event) {
	var x = 0;
	var y = 0;
	if (!event) {
		var event = window.event; 
	}
	if (event.pageX || event.pageY) 	{
		x = event.pageX;
		y = event.pageY;
	} else if (event.clientX || event.clientY) 	{
		x = event.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
		y = event.clientY + document.body.scrollTop + document.documentElement.scrollTop;
	}
	var x_y = new Array();
	x_y['x'] = x;
	x_y['y'] = y;
	return x_y;
}

Du brauchst außerdem drei Variablen (ich mache das in Form von einem Array), die Global definiert sind.
PHP:
var drag = new Array();
drag['id'] = '';
drag['x'] = 0;
drag['y'] = 0;
drag['id'] ist der Container, der gerade bewegt wird. Das kannst du jedoch fallen lassen, falls es nur einen Container gibt, der bewegt werden muss.
drag['x'] ist die X-Koordinate der Maus verglichen zum Dragger und nicht zum Dokument.
drag['y'] ist die Y-Koordinate der Maus verglichen zum Dragger und nicht zum Dokument.


Nun brauchst du verschiedene Event-Listener.
Ein "onmousedown" beim Dragger um das Dragging zu beginnen.
Ein "onmousemove" im Dokument um falls die Maus noch gedrückt ist, den Container zu bewegen.
Ein "onmouseup" im Dokument um ein Dragging zu beenden.


Nun fangen wir mit dem einfachsten an, die mouseup-Funktion.
PHP:
function mousereleasing() {
	drag['id'] = '';
	drag['x'] = 0;
	drag['y'] = 0;
}
Diese setzt alle globalen nötigen Informationen des Containers auf 0. Das Dragging ist gestoppt.

Nun die allgemeine Mousemove-Funktion:
PHP:
function mousemoving(event) {
	if (drag['id']!='') {
		var coords = getCoords(event);
		document.getElementById(drag['id']).style.top = coords['y'] - drag['y'] + 'px';
		document.getElementById(drag['id']).style.left = coords['x'] - drag['x'] + 'px';
		if (document.selection) {
			document.selection.empty();
		} else if(window.getSelection) {
			selected = window.getSelection();
			if(selected && selected.removeAllRanges) {
				selected.removeAllRanges();
			}
		}
	}
}
Der If ganz zum Anfang ist eine Bedingung, die besagt, dass das Dragging in Gang ist, dass die Maus also noch "down" ist.
Wichtig ist es, das left und top nicht direkt von der Mausposition abhängig zu machen, sondern auch von der Position verglichen zum oberen und linken Rand der Draggers (die drag['x'] und drag['y']).
Das document.selection, bzw. das window.getSelection ist vorallem dafür vorgesehen, dass schnelles Dragging hintereinander keine Problem verursacht. Der Firefox draggt das Element beispielsweise nicht, sondern ändert den Cursor um zu zeigen, dass man den markierten Text nicht irgendwo in bewegen kann. (Wenn du es fallen lässt merkst du es relativ schnell.)


Da Internet Explorer Probleme damit hat globale Events auf "window" zu setzen, rate ich dir folgendes an:
PHP:
if (document.all) {
	document.onmousemove = mousemoving;
	document.onmouseup = mousereleasing;
} else {
	window.onmousemove = mousemoving;
	window.onmouseup = mousereleasing;
}

Nun die Initialisierung des Draggings.
PHP:
document.getElementById("dragger").onmousedown = function(event) {
	var coords = getCoords(event);
	drag['id'] = this.parentNode.getAttribute('id');
	drag['x'] = coords['x'] - parseInt(document.getElementById(drag['id']).style.left);
	drag['y'] = coords['y'] - parseInt(document.getElementById(drag['id']).style.top);
};
Wichtig hierbei ist, dass du das onmousedown-Event nicht auf den Container setzt, sondern auf den Dragger. Der Dragger befindet sich in dem Fall direkt im Container, der bewegt sein muss (deswegen parentNode). Sollte er sich in einem Element tiefer befinden, einfach noch ein parentNode hinzufügen.



Ich hoffe, dass das einigermaßen verständlich ist.



Edit
Falls der Container nicht von Natur aus ein Style-Attribut besitzt, würde ich das noch hinzufügen:
PHP:
try {
	document.addEventListener("DOMContentLoaded", start, false);
} catch(e) {
	window.onload = start;
}
function start() {
	document.getElementById("container").style.left = "300px";
	document.getElementById("container").style.top = "300px";
	document.getElementById("container").style.position = "absolute";
}
 
Zuletzt bearbeitet:
PHP:
var drag = new Array();
drag['id'] = '';
drag['x'] = 0;
drag['y'] = 0;
Arrays sind zwar Objekte, aber sind in JavaScript nicht assoziativ. Deshalb sollten Index rein numerisch sein. Wenn du ein Objekt willst, warum nimmst du dann keins?

Deine Verwendung von try...catch ist etwas verwunderlich. Warum sollte addEventListener einen Fehler werfen? try...catch ist dazu da um auf Fehler zu reagieren und nicht um zu testen, ob's eine Funktionalität gibt. Zumal man auf die Verfügbarkeit von DOMContentLoaded eh nicht testen kann.
 
PHP:
var drag = new Array();
drag['id'] = '';
drag['x'] = 0;
drag['y'] = 0;
Arrays sind zwar Objekte, aber sind in JavaScript nicht assoziativ. Deshalb sollten Index rein numerisch sein. Wenn du ein Objekt willst, warum nimmst du dann keins?

Deine Verwendung von try...catch ist etwas verwunderlich. Warum sollte addEventListener einen Fehler werfen? try...catch ist dazu da um auf Fehler zu reagieren und nicht um zu testen, ob's eine Funktionalität gibt. Zumal man auf die Verfügbarkeit von DOMContentLoaded eh nicht testen kann.

Ich denke mal, dass das mit dem Array() eine schlechte Angewohnheit von PHP ist.

addEventListener funktioniert nicht in älteren IEs. Kannst von mir aus ein else if setzen.
Funktionell ändert sich aber dabei nichts, würde ich sagen.
 
Doch du vermeidest im vornherein einen Fehler und um Fehlerprävention geht es immer beim programmieren. try...catch ist für Fälle, wo man sich nicht sicher sein kann. Z.b. ob ein JSON-Parser nicht doch einen Fehler wirft. In JavaScript braucht man try...catch nicht sehr häufig.
 
Ja, das kann man dann dementsprechend anpassen.
Mit funktionell meinte ich eigentlich, dass es seinen gemeinten Zweck erfüllt ;ugl


Ich denke der Rest des Codes müsste eigentlich gut sein.
 
Status
Für weitere Antworten geschlossen.
Zurück
Oben