Tipps und Änderungsvorschläge für meine Drag'n Drop - Klasse
Gawin
- javascript
Hi Leute,
ich hab ne Drag'n Drop - Klasse geschrieben und würde gerne eure meinungen und verbesserungsvorschläge von euch wissen.
Hier die drag_n_drop.js:
/********************************************************/
/* Auschnitt aus meiner mainlibary die ich für */
/* die DragNDrop-Klasse genutzt habe */
/********************************************************/
mouse_pos = function(e) {
if(!e) e = window.event;
var body = (window.document.compatMode && window.document.compatMode == "CSS1Compat") ?
window.document.documentElement : window.document.body;
pos={X:null,Y:null};
try{
pos.Y = e.pageY;
pos.X = e.pageX;
}catch(e){
pos.Y = e.clientY + body.scrollTop - body.clientTop;
pos.X = e.clientX + body.scrollLeft - body.clientLeft;
}
return pos;
}
_$ = function(clas, parent){
var obj = (document.getElementById(parent) || document.body).getElementsByTagName('*');
var ret = new Array();
for( var i=0, l=obj.length; i<l; i++){
if(obj[i].getAttribute("class")){
var erg = obj[i].getAttribute("class").split(" ");
for(var i2=0,l2=erg.length; i2<l2; i2++){
if(clas == erg[i2]){ ret.push(obj[i]); }
}
}
}
return ret;
}
hasClass = function(obj, clas){
if(obj.getAttribute("class")!=null){
var clas_erg = obj.getAttribute("class").split(" ");
for(var i=0, l=clas_erg.length; i<l; i++){
if(clas_erg[i] === clas) return true;
}
return false;
}else return false;
}
function DragNDrop(){
_this = this; // Selbstreferenz
this.drag_obj = null; // Speichert das aktuell zu bewgende Objekt
this.drag_objects = _$("drag_obj"); // Speichert alle mit class="drag_obj" ab
this.windows = _$("window"); // Speichert alle mit class="window" ab
this.drag_obj_pos = {X:null,Y:null}; // Mausposition relative zum Dragobjekt
this.pos = {X:null,Y:null}; // Mausposition
/********************************************************/
for(var i=0, l=this.windows.length; i<l; i++){
this.windows[i].onmousedown = function(e){
_this.z_index();
this.style.zIndex = 9999;
}
}
/********************************************************/
for(var i=0, l=this.drag_objects.length; i<l; i++){
var obj = this.drag_objects[i];
obj.onmousedown = function(e){
_this.drag_obj = this;
_this.pos = mouse_pos(e);
if(!hasClass(this.parentNode, "window")){
_this.drag_obj_pos.Y = _this.pos.Y-this.offsetTop;
_this.drag_obj_pos.X = _this.pos.X-this.offsetLeft;
this.style.zIndex = 10000;
}else{
_this.drag_obj_pos.Y = _this.pos.Y-this.parentNode.offsetTop;
_this.drag_obj_pos.X = _this.pos.X-this.parentNode.offsetLeft;
this.parentNode.style.zIndex = 10000;
}
this.style.cursor = "move"; // Ändert den Cursor in eine Hand
_this.z_index();
}
}
/********************************************************/
document.onmousemove = function(e){
if(_this.drag_obj != null){
_this.pos = mouse_pos(e);
var posX = _this.pos.X-_this.drag_obj_pos.X;
var posY = _this.pos.Y-_this.drag_obj_pos.Y;
if(!hasClass(_this.drag_obj.parentNode, "window")){
with(_this.drag_obj.style){
position = "absolute";
top = posY + "px";
left = posX + "px";
}
}else{
with(_this.drag_obj.parentNode.style){
position = "absolute";
top = posY + "px";
left = posX + "px";
}
}
}
}
/********************************************************/
document.onmouseup = function(e){
if(_this.drag_obj){
var obj = _this.drag_obj;
_this.drag_obj.style.cursor = "default"; // setzt den Cursor wieder auf normal
_this.z_index();
if(hasClass(_this.drag_obj.parentNode, "window")){
_this.drag_obj.parentNode.style.zIndex = 9999;
}else{
_this.drag_obj.style.zIndex = 9999;
}
_this.drag_obj = null; // Beendet
}
}
/********************************************************/
this.z_index = function(){
for(var i=0, l=_this.drag_objects.length; i<l; i++){
var obj = _this.drag_objects;
if(hasClass(obj[i].parentNode, "window")) var _obj = obj[i].parentNode;
else var _obj = obj[i];
if(_obj.style && _obj.style.zIndex){
_obj.style.zIndex = eval(_obj.style.zIndex+"-1");
}
}
}
}
window.onload = function(){
var dragClass = new DragNDrop();
}
Und hier die index.html:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta name="author" content="Robin (Gawin) Gerhartz" />
<meta http-equiv="content-type" content="text/html; charset=UTF-8" />
<meta name="description" content="Drag'n Drop Testseite" />
<script type="text/javascript" src="drag_n_drop.js"></script>
<style type="text/css" media="screen">
*{
margin:0;
padding:0;
}
body{
background-color: #adadad;
overflow:hidden;
}
.div{
height:50px;
width:50px;
}
.window{
background-color:white;
width:150px;
}
.window .win_content{
background-color:black;
width:150px;
height:150px;
}
.window p{
text-align: center;
}
</style>
<title>Drag'n Drop</title>
</head>
<body>
<div id="www" class="drag_obj div" style="background-color:navy;"></div>
<div id="firefox" class="drag_obj div" style="background-color:yellow;"></div>
<div class="window">
<div class="drag_obj">
<p>test</p>
</div>
<div class="win_content">
</div>
</div>
<div class="window">
<div class="drag_obj">
<p>test2</p>
</div>
<div class="win_content" style="background-color:blue;">
</div>
</div>
<div class="window">
<div class="drag_obj">
<p>test3</p>
</div>
<div class="win_content" style="background-color:red;">
</div>
</div>
</body>
</html>
Eine Demoseite findet Ihr HIER.
Würde mich um feedback freuen.
Gruss Gawin
Hallo,
Vor allem Stilistisches und Optimierungsmöglichkeiten:
mouse_pos = function(e) {
Ein Haufen an globaler Objekte und Funktionen ist nicht so schön - besser modularisieren und kapseln.
try{
pos.Y = e.pageY;
pos.X = e.pageX;
}catch(e){
pos.Y = e.clientY + body.scrollTop - body.clientTop;
pos.X = e.clientX + body.scrollLeft - body.clientLeft;
}
try-catch ist keine brauchbare Feature-Abfrage. Außerdem wird der Zugriff auf e.pageX keine Exception werfen, sondern e.pageX ergibt einfach undefined. Das dürfte in Browsern, die pageX nicht kennen, also nicht wie gewünscht funktionieren.
Prüfe sinnvoll auf das Vorhandensein der pageX-Eigenschaft sowie auf die Brauchbarkeit des Wertes. Siehe http://aktuell.de.selfhtml.org/artikel/javascript/objektabfragen/.
Verschiedene Abfragen sind möglich:
if (typeof e.pageX == 'number') {…}
if (typeof e.pageX != 'undefined') {…}
if ('pageX' in e) {…}
if (e.hasOwnProperty('pageX')) {…}
usw.
Das wäre alles sinnvoller, die erste Methode würde ich wählen.
_$ = function(clas, parent){
var obj = (document.getElementById(parent) || document.body).getElementsByTagName('*');
Mache dich einmal mit
document.getElementsByClassName
sowie
document.querySelectorAll
vertraut.
Wenn der Browser sie kennt (Feature-Abfrage), solltest du der Einfachheit halber diese benutzen.
if(obj[i].getAttribute("class")){
getAttribute ist meist unnötig, verwende besser .className.
getAttribute('class') liefert in älteren IEs zudem nichts zurück, className ist da die einzige browserübergreifende Möglichkeit.
var erg = obj[i].getAttribute("class").split(" ");
for(var i2=0,l2=erg.length; i2<l2; i2++){
if(clas == erg[i2]){ ret.push(obj[i]); }
}
Du hast doch eine hasClass-Helferfunktion, wieso nutzt du sie hier nicht? :)
Darüber hinaus: Neuere Browser kennen element.classList.contains(). Kann man auch mit einer Feature-Abfrage ermitteln. Einen Fallback mit einer Logik, wie du sie jetzt hast, bräuchtest du natürlich weiterhin.
function DragNDrop(){
_this = this; // Selbstreferenz
Das erzeugt eine globale Variable. Du hast das »var « davor vergessen.
(Gut, dein Konstruktor ist ohnehin nicht dafür ausgelegt, pro Dokument mehr als einmal aufgerufen zu werden…)
/********************************************************/
for(var i=0, l=this.windows.length; i<l; i++){
this.windows[i].onmousedown = function(e){
_this.z_index();
this.style.zIndex = 9999;
}
}
Allgemein solltest du Funktionen außerhalb von Schleifen notieren, wenn du sie als Event-Handler an viele Elemente hängst. So wird nämlich für jedes Element eine neue (wenn auch gleiche) Funktion erzeugt.
_this.drag_obj_pos.Y = _this.pos.Y-this.offsetTop;
_this.drag_obj_pos.X = _this.pos.X-this.offsetLeft;
offsetTop und offsetLeft beziehen sich nicht notwendig auf den Viewport, sofern es absolute oder relativ positionierte Eltern gibt. Verwende am besten getBoundingClientRect, wenn es unterstützt wird (Feature-Abfrage), oder zumindest ein solches Script.
if(!hasClass(_this.drag_obj.parentNode, "window")){
with(_this.drag_obj.style){
position = "absolute";
top = posY + "px";
left = posX + "px";
}
}else{
with(_this.drag_obj.parentNode.style){
position = "absolute";
top = posY + "px";
left = posX + "px";
}
}
with ist hier nicht falsch, wird aber mittlerweile als veraltet und problematisch angesehen, weil es oftmals Fehler produzieren kann. Hier ginge auch folgendes:
var style = _this.drag_obj.parentNode.style;
style.position = "absolute";
style.top = posY + "px";
style.left = posX + "px";
Das ist eindeutiger, weil posX und posY nicht erst am style-Objekt gesucht werden. (Gut, dort gibt es höchstwahrscheinlich keine solche Eigenschaften, daher ist das mehr ein genereller Hinweis.)
if(_obj.style && _obj.style.zIndex){
_obj.style.zIndex = eval(_obj.style.zIndex+"-1");
}
Das eval ist hier (wie in den meisten Fällen) unnötig. Einen String kannst du mit http://de.selfhtml.org/javascript/objekte/unabhaengig.htm#parse_int@title=parseInt in eine Zahl umwandeln.
var style = _obj.style;
if (style.zIndex) {
style.zIndex = parseInt(style.zIndex) - 1;
}
window.onload = function(){
var dragClass = new DragNDrop();
}
Siehe auch alternative onload-Techniken.
Die Logik habe ich mir jetzt nicht im Detail angesehen, aber vom Prinzip her funktioniert Drag and Drop auf Basis von Mausevents immer gleich.
Mathias
Erstmal danke für deine ausführliche Antwort.
Hab das meiste direkt umsetzen können. Vorallem danke für den Hinweis mit der funktionsdefinition in Schleifen. Hab aber mit ein paar sachen schwirigkeiten.
Mache dich einmal mit
document.getElementsByClassName
sowie
document.querySelectorAll
vertraut.
Wenn der Browser sie kennt (Feature-Abfrage), solltest du der Einfachheit halber diese benutzen.
Also bei mir funktioniert das irgent wie nirgendwo. Könntest du mir vllt ein nachvollziehbares beispiel geben?
if(obj[i].getAttribute("class")){
getAttribute ist meist unnötig, verwende besser .className.
getAttribute('class') liefert in älteren IEs zudem nichts zurück, className ist da die einzige browserübergreifende Möglichkeit.
Muss ich da die ganze Klasse umschreiben oder kann ich irgent wie dem "all" Objekt einen Objektverweis übergeben?
window.onload = function(){
var dragClass = new DragNDrop();
}Siehe auch alternative onload-Techniken.
Wenn ich die Klasse über die Funktion "contentLoaded(window, init())" aufrufe kennt der "document.body" noch nicht und somit die "on"-handler die ich per Klasse zuweise nicht.
Hoffe du kannst mir noch helfen diese probleme zu lösen.
Gruss Gawin
Hi,
Wenn ich die Klasse über die Funktion "contentLoaded(window, init())" aufrufe kennt der "document.body" noch nicht und somit die "on"-handler die ich per Klasse zuweise nicht.
ich weiß nicht, ob das ein C&P-Fehler von dir ist, aber im Beispielcode von molily erwartet die Funktion contentLoaded als zweiten Parameter eine Funktion, nicht den Rückgabewert der Funktion init.
Dies würde auch erklären, warum die Funktion init zum falschen Zeitpunkt aufgerufen wird. Wenn du die Klammern schreibst, wird beim Hinzufügen des onload-Handlers bereits init() aufgerufen, nicht erst dann, wenn der Handler dann wirklich feuert.
Bis die Tage,
Matti
ich weiß nicht, ob das ein C&P-Fehler von dir ist, aber im Beispielcode von molily erwartet die Funktion contentLoaded als zweiten Parameter eine Funktion, nicht den Rückgabewert der Funktion init.
Danke für den hinweis lag nur an der Klammer, vergess immer das dass dann direckt aufgerufen wird.
Gruss Gawin
Hi Hab mein _$ und hasClass Funktionen nochmal überarbeitet.
Aber irgent wo hab ich hab ich nen Fehler denn in <=IE7 funktioniert es immer noch nicht.
Hoffe es kann mir wer helfen.
_$ = function(clas, parent){
parent = parent || document;
if(document.getElementsByClassName && document.getElementsByClassName(clas)){
var el = parent;
var ret = el.getElementsByClassName(clas);
}else if(document.querySelectorAll && document.querySelectorAll('.class')){
var ret = document.querySelectorAll('.class');
}else{
var obj = (document.getElementById(parent) || document.body).getElementsByTagName('*');
var ret = new Array();
for( var i=0, l=obj.length; i<l; i++){
if(hasClass(obj[i], clas)) ret.push(obj[i]);
}
}
return ret;
}
hasClass = function(obj, clas){
var doc = document.all || document;
if(doc.obj && doc.obj.className != null){
var clas_erg = doc.obj.className.split(" ");
}else if(obj.getAttribute("class")!=null){
var clas_erg = obj.getAttribute("class").split(" ");
}else return false;
if(clas_erg){
for(var i=0, l=clas_erg.length; i<l; i++){
if(clas_erg[i] === clas) return true;
}
return false;
}
}
Hallo!
if(document.getElementsByClassName && document.getElementsByClassName(clas)){
var el = parent;
var ret = el.getElementsByClassName(clas);
}else if(document.querySelectorAll && document.querySelectorAll('.class')){
var ret = document.querySelectorAll('.class');
Hier rufst du jeweils getElementsByClassName und querySelectorAll jeweils zweimal aus. Das ist nicht Sinn der Sache. Wenn diese Funktionen existieren, dann kannst du auch davon ausgehen, dass der Rückgabewert »truthy« ist, also bei der Abfrage if(document.getElementsByClassName(clas)) true ergibt.
(Wenn die Funktionen existieren, aber falsch implementiert sind, dann hilft der Test des Rückgabewerts auch nur wenig.)
Daher reicht:
if (parent.getElementsByClassName) {
return parent.getElementsByClassName(clas);
}
/* Andernfalls mit parent.getElementsByTagName("*") arbeiten und die Klasse aller zurückgegebenen Elemente manuell prüfen */
Das durchsucht dann auch nur die Kinder von parent, nicht vom ganzen Dokument.
Man kann sich für eines von den getElementsByClassName und querySelectorAll entscheiden und sollte das breiter unterstützte getElementsByClassName wählen. Ich hatte nur der Vollständigkeit halber auf beide hingewiesen.
Ein zusätzlicher Block mit querySelectorAll ist nicht nötig, denn es gibt keinen Browser, der QSA kennt, aber nicht das ältere getElementsByClassName.
hasClass = function(obj, clas){
var doc = document.all || document;
document brauchst du hier nicht, auch nicht document.all.
if(doc.obj && doc.obj.className != null){
doc.obj wird einfach undefined liefern. obj ist doch ein Elementobjekt, du kannst es direkt nutzen. Beispiel:
if (!obj) return null;
if (obj.classList && obj.classList.contains) {
return obj.classList.contains(clas);
}
var className = obj.className;
if (!className) return false;
/* Dann mit der for-Schleife nach einem Treffer suchen */
var clas_erg = doc.obj.className.split(" ");
}else if(obj.getAttribute("class")!=null){
var clas_erg = obj.getAttribute("class").split(" ");
Einen zusätzlichen Block für getAttribute braucht du nicht. className reicht völlig aus, das kennt jeder Browser.
if(clas_erg){
clas_erg ist immer ein Array, die Prüfung ist also unnötig.
for(var i=0, l=clas_erg.length; i<l; i++){
if(clas_erg[i] === clas) return true;
}
return false;
Soweit in Ordnung.
Mathias
Danke übernimm die Sachen sofort die ich noch nicht übernommen habe.
Gruss Gawin
if (!obj) return null;
if (obj.classList && obj.classList.contains) {
return obj.classList.contains(clas);
}var className = obj.className;
if (!className) return false;/* Dann mit der for-Schleife nach einem Treffer suchen */
Klappt nicht in alten IE's hab mich für das entschieden:
~~~javascript
hasClass = function(obj, clas){
if(document.all){
if(clas == obj.className) return true;
}else if(obj.getAttribute("class")!=null){
var clas_erg = obj.getAttribute("class").split(" ");
}else return false;
for(var i=0, l=clas_erg.length; i<l; i++){
if(clas_erg[i] === clas) return true;
}
}
Ok, langsam wirds peinlich, hab den Fehler gefunden.
Aber irgent wie schaffen IE5.5-IE7 es nicht die DIV's mit "class='dragobj'" zu verschieben,
verschiebt aber die sachen mit "class='window'" wunderbar.
Der IE8 verweigert sogar glatt alles!!!
Aber ich weiss einfach nicht warum.
Hier die aktualisierte drag_n_drop.js:
/********************************************************/
/* Auschnitt aus meiner mainlibary die ich für */
/* die DragNDrop-Klasse genutzt habe */
/********************************************************/
mouse_pos = function(e) {
if(!e) e = window.event;
var body = (window.document.compatMode && window.document.compatMode == "CSS1Compat") ?
window.document.documentElement : window.document.body;
pos={X:null,Y:null};
if (typeof e.pageX == 'number'){
pos.Y = e.pageY;
pos.X = e.pageX;
}else{
pos.Y = e.clientY + body.scrollTop - body.clientTop;
pos.X = e.clientX + body.scrollLeft - body.clientLeft;
}
return pos;
}
_$ = function(clas, parent){
parent = parent || document;
if(document.getElementsByClassName && document.getElementsByClassName(clas)){
var el = parent;
var ret = el.getElementsByClassName(clas);
}else if(document.querySelectorAll && document.querySelectorAll('.class')){
var ret = document.querySelectorAll('.class');
}else{
var obj = document.all ? document.all : (document.getElementById(parent) || document.body).getElementsByTagName('*');
var ret = new Array();
for( var i=0, l=obj.length; i<l; i++){
if(hasClass(obj[i], clas)) ret.push(obj[i]);
}
}
return ret;
}
hasClass = function(obj, clas){
if(document.all && obj.className != null){
if(clas == obj.className) return true;
}else if(obj.getAttribute("class")!=null){
var clas_erg = obj.getAttribute("class").split(" ");
}else return false;
if(clas_erg){
for(var i=0, l=clas_erg.length; i<l; i++){
if(clas_erg[i] === clas) return true;
}
return false;
}
}
function DragNDrop(){
var _this = this; // Selbstreferenz
this.drag_obj = null; // Speichert das aktuell zu bewgende Objekt
this.drag_objects = _$("dragobj"); // Speichert alle mit class="drag_obj" ab
this.windows = _$("window"); // Speichert alle mit class="window" ab
this.drag_obj_pos = {X:null,Y:null}; // Mausposition relative zum Dragobjekt
this.pos = {X:null,Y:null}; // Mausposition
this.findPos = function(obj) {
var curleft = curtop = 0;
if (obj.offsetParent) {
do {
curleft += obj.offsetLeft;
curtop += obj.offsetTop;
} while (obj = obj.offsetParent);
return {X:curleft,Y:curtop};
}
}
/********************************************************/
this.windowMouseDown = function(){
_this.z_index();
this.style.zIndex = 9999;
}
for(var i=0, l=this.windows.length; i<l; i++){
this.windows[i].onmousedown = this.windowMouseDown;
}
/********************************************************/
this.objMouseDown = function(e){
_this.drag_obj = this;
_this.pos = mouse_pos(e);
if(!hasClass(this.parentNode, "window")){
var objPos = _this.findPos(this);
//alert(objPos.X+" : "+objPos.Y);
_this.drag_obj_pos.Y = _this.pos.Y-this.offsetTop;
_this.drag_obj_pos.X = _this.pos.X-this.offsetLeft;
this.style.zIndex = 10000;
}else{
var objPos = _this.findPos(this.parentNode);
_this.drag_obj_pos.Y = _this.pos.Y-this.parentNode.offsetTop;
_this.drag_obj_pos.X = _this.pos.X-this.parentNode.offsetLeft;
this.parentNode.style.zIndex = 10000;
}
this.style.cursor = "move"; // Ändert den Cursor in eine Hand
_this.z_index();
}
for(var i=0, l=this.drag_objects.length; i<l; i++){
var obj = this.drag_objects[i];
obj.onmousedown = this.objMouseDown;
}
/********************************************************/
document.onmousemove = function(e){
if(_this.drag_obj != null){
_this.pos = mouse_pos(e);
var posX = _this.pos.X-_this.drag_obj_pos.X;
var posY = _this.pos.Y-_this.drag_obj_pos.Y;
if(!hasClass(_this.drag_obj.parentNode, "window")){
var style = _this.drag_obj.style;
style.position = "absolute";
style.top = posY + "px";
style.left = posX + "px";
}else{
var style = _this.drag_obj.parentNode.style;
style.position = "absolute";
style.top = posY + "px";
style.left = posX + "px";
}
}
}
/********************************************************/
document.onmouseup = function(e){
if(_this.drag_obj){
var obj = _this.drag_obj;
_this.drag_obj.style.cursor = "default"; // setzt den Cursor wieder auf normal
_this.z_index();
if(hasClass(_this.drag_obj.parentNode, "window")){
_this.drag_obj.parentNode.style.zIndex = 9999;
}else{
_this.drag_obj.style.zIndex = 9999;
}
_this.drag_obj = null; // Beendet
}
}
/********************************************************/
this.z_index = function(){
for(var i=0, l=_this.drag_objects.length; i<l; i++){
var obj = _this.drag_objects;
if(hasClass(obj[i].parentNode, "window")) var _obj = obj[i].parentNode;
else var _obj = obj[i];
if(_obj.style && _obj.style.zIndex){
_obj.style.zIndex = parseInt(_obj.style.zIndex)-1;
}
}
}
}
function init(){
var dragClass = new DragNDrop();
}
contentLoaded(window, init);
Die index.html is gleich geblieben ausser das "class='drag_obj'" zu "class='dragobj'" wurde. Demoseite findet Ihr wieder HIER.
Hoffe mir kann jemand helfen.
Gruss Gawin
So, jetzt Funktioniert es in allen IE's ausser im IE8.
Hoffe es kann mir wer helfen.
drag_n_drop.js:
/********************************************************/
/* Auschnitt aus meiner mainlibary die ich für */
/* die DragNDrop-Klasse genutzt habe */
/********************************************************/
_$ = function(clas, parent){
pardoc = parent || document;
if(document.getElementsByClassName){
return pardoc.getElementsByClassName(clas);
}else if(document.querySelectorAll){
return document.querySelectorAll('.class');
}else{
var obj = document.all ? document.all : (document.getElementById(parent) || document.body).getElementsByTagName('*');
var ret = new Array();
for( var i=0, l=obj.length; i<l; i++){
if(hasClass(obj[i], clas)) ret.push(obj[i]);
}
}
return ret;
}
hasClass = function(obj, clas){
var clas_erg = new Array();
if(obj.classList && obj.classList.contains(clas)){
return true;
}else if(document.all){
clas_erg = obj.className.split(" ");
}else if(obj.getAttribute("class")!=null){
clas_erg = obj.getAttribute("class").split(" ");
}else return false;
for(var i=0, l=clas_erg.length; i<l; i++){
if(clas_erg[i] === clas) return true;
}
}
mouse_pos = function(e) {
if(!e) e = window.event;
var body = (window.document.compatMode && window.document.compatMode == "CSS1Compat") ?
window.document.documentElement : window.document.body;
pos={X:null,Y:null};
if(typeof e.pageY == "number"){
pos.Y = e.pageY;
pos.X = e.pageX;
}else{
pos.Y = e.clientY + body.scrollTop - body.clientTop;
pos.X = e.clientX + body.scrollLeft - body.clientLeft;
}
return pos;
}
function DragNDrop(){
var _this = this; // Selbstreferenz
this.drag_obj = null; // Speichert das aktuell zu bewgende Objekt
this.drag_objects = _$("dragobj"); // Speichert alle mit class="drag_obj" ab
this.windows = _$("window"); // Speichert alle mit class="window" ab
this.drag_obj_pos = {X:null,Y:null}; // Mausposition relative zum Dragobjekt
this.pos = {X:null,Y:null}; // Mausposition
/********************************************************/
this.windowMouseDown = function(){
_this.z_index();
this.style.zIndex = 9999;
}
for(var i=0, l=this.windows.length; i<l; i++){
this.windows[i].onmousedown = this.windowMouseDown;
}
/********************************************************/
this.objMouseDown = function(e){
if(!e) e = window.event;
_this.drag_obj = this;
_this.pos = mouse_pos(e);
if(!hasClass(this.parentNode, "window")){
_this.drag_obj_pos.Y = _this.pos.Y-this.offsetTop;
_this.drag_obj_pos.X = _this.pos.X-this.offsetLeft;
this.style.zIndex = 10000;
}else{
_this.drag_obj_pos.Y = _this.pos.Y-this.parentNode.offsetTop;
_this.drag_obj_pos.X = _this.pos.X-this.parentNode.offsetLeft;
this.parentNode.style.zIndex = 10000;
}
this.style.cursor = "move"; // Ändert den Cursor in eine Hand
_this.z_index();
}
for(var i=0, l=this.drag_objects.length; i<l; i++){
var obj = this.drag_objects[i];
obj.onmousedown = this.objMouseDown;
}
/********************************************************/
document.onmousemove = function(e){
if(!e) e = window.event;
if(_this.drag_obj != null){
_this.pos = mouse_pos(e);
var posX = _this.pos.X-_this.drag_obj_pos.X;
var posY = _this.pos.Y-_this.drag_obj_pos.Y;
if(!hasClass(_this.drag_obj.parentNode, "window")){
var style = _this.drag_obj.style;
style.position = "absolute";
style.top = posY + "px";
style.left = posX + "px";
}else{
var style = _this.drag_obj.parentNode.style;
style.position = "absolute";
style.top = posY + "px";
style.left = posX + "px";
}
}
}
/********************************************************/
document.onmouseup = function(e){
if(_this.drag_obj){
var obj = _this.drag_obj;
obj.style.cursor = "default"; // setzt den Cursor wieder auf normal
_this.z_index();
if(hasClass(obj.parentNode, "window")){
obj.parentNode.style.zIndex = 9999;
}else{
obj.style.zIndex = 9999;
}
_this.drag_obj = null; // Beendet
}
}
/********************************************************/
this.z_index = function(){
for(var i=0, l=_this.drag_objects.length; i<l; i++){
var obj = _this.drag_objects;
if(hasClass(obj[i].parentNode, "window")) var _obj = obj[i].parentNode;
else var _obj = obj[i];
if(_obj.style && _obj.style.zIndex){
_obj.style.zIndex = parseInt(_obj.style.zIndex)-1;
}
}
}
}
function init(){
var dragClass = new DragNDrop();
}
contentLoaded(window, init);
index.html:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta name="author" content="Robin (Gawin) Gerhartz" />
<meta http-equiv="content-type" content="text/html; charset=UTF-8" />
<meta name="description" content="Drag'n Drop Testseite" />
<script type="text/javascript" src="contentloaded.js"></script>
<script type="text/javascript" src="drag_n_drop.js"></script>
<style type="text/css" media="screen">
*{
margin:0;
padding:0;
}
body{
background-color: #adadad;
overflow:hidden;
}
.div{
height:50px;
width:50px;
}
.window{
background-color:white;
width:150px;
}
.window .win_content{
background-color:black;
width:150px;
height:150px;
}
.window p{
text-align: center;
}
</style>
<title>Drag'n Drop</title>
</head>
<body>
<div id="www" class="dragobj div" style="background-color:navy;"></div>
<div id="firefox" class="dragobj div" style="background-color:yellow;"></div>
<div class="window">
<div class="dragobj">
<p>test</p>
</div>
<div class="win_content">
</div>
</div>
<div class="window">
<div class="dragobj">
<p>test2</p>
</div>
<div class="win_content" style="background-color:blue;">
</div>
</div>
<div class="window">
<div class="dragobj">
<p>test3</p>
</div>
<div class="win_content" style="background-color:red;">
</div>
</div>
</body>
</html>
und die Demoseite wie immer Hier.