dropper: Drag & Drop mit onclick tadellos - aber für position:relative?

Moin!

Frage: Wie bekommt man relativ positionierte Elemente mit drag&drop
       in den Griff?

Habe in vielen Foren gesehen, dass andere dieselben Probleme
mit drag&drop haben wie ich:
  -> Verzögerung bei Bildern, ungewollte Textmarkierungen, ...

Das vielen drag-and-droppern bekannte script von Daniel Thoma
[http://aktuell.de.selfhtml.org/artikel/javascript/draganddrop/index.htm]
arbeitet mit den event handlern onmousedown und onmouseup.

Nimmt man ein paar kleine Veränderungen vor, so lassen sich
auch Bilder und Schriften tadellos draggen und droppen -
nur leider nur abs. pos. Objekte; bei rel. pos. kann es passieren, dass,
will man das Objekt droppen, dieses sich nicht "unter" dem Cursor
befindet und somit der event handler onclick nicht greift:

  
var dragobjekt = null;  
  
var dragx = 0;  
var dragy = 0;  
  
var posX = 0;  
var posY = 0;  
  
function draginit() {  
  document.onmousemove = drag;  
} // und KEIN document.onmouseup = dragstop  
  
var busy = 0; // hinzugefügt  
  
function dragstart(element) {  
  if (busy == 0) { // hinzugefügt  
     busy = 1; // hinzugefügt  
     dragobjekt = element;  
     dragx = posX - dragobjekt.offsetLeft;  
     dragy = posY - dragobjekt.offsetTop;  
  }  
}  
  
function dragstop() {  
  dragobjekt=null;  
  busy = 0; // hinzugefügt  
}  
  
function drag(e) {  
  posX = document.all ? window.event.clientX : e.pageX;  
  posY = document.all ? window.event.clientY : e.pageY;  
  if (dragobjekt != null) {  
     dragobjekt.style.left = (posX - dragx) + "px";  
     dragobjekt.style.top = (posY - dragy) + "px";  
  }  
}  

HTML:
[code lang=html
<body onload="javascript:draginit()">

<img src="bild.png"
     style="position:absolute; left:50px; top:50px;"
     onclick=
            "if(busy==0){javascript:dragstart(this);}
            else {javascript:dragstop();}"
[/code]

lieben gruß

  1. hi ho,

    probiers mal so

      
    function drag(e) {  
      posX = document.all ? window.event.clientX : e.pageX;  
      posY = document.all ? window.event.clientY : e.pageY;  
      if (dragobjekt != null) {  
         dragobjekt.style.position = "absolute";  
         dragobjekt.style.left = (posX - dragx) + "px";  
         dragobjekt.style.top = (posY - dragy) + "px";  
      }  
    }  
    
    

    hoffe das hilft evtl. ist zwar nicht unbedingt sauber aber ein Ansatz.

    mfg

    1. dragobjekt.style.position = "absolute";

      hey danke!
      manchmal ist's halt einfach zu offensichtlich, um in's auge zu springen hehe
      ausprobiert - klappt - wunderbar
      gruß

    2. dragobjekt.style.position = "absolute";

      obwohl, beim 2. anlauf gab's dann doch schwierigkeiten.
      je nachdem, wo man das relativ positionierte objekt anklick,
      ist es "unter" dem cursor oder auch nicht.
      aber kriege ich mit etwas rumdoktoren bestimmt schon noch hin...
      :-}

    3. oh oh oh,

      margin-left war das problem.
      hyrocles, du hattest recht: ...style.position = "absolute" klappt.
      probleme wird es geben, wenn man das element mit margin-x verschiebt.
      bsp.: {left:200px; top:0px; margin-left:100px; width:50px;}
      -> dann ist das element nicht "unter" dem cursor, da wo es sein sollte,
         sondern 100px (margin-left) weiter rechts.
      also: mit etwas zusatz-gecode klappt d&d dann doch für alle elemente
            in jeder positionierung :-}

      1. Nachtrag:

        function dragstart(element,marginLeft,marginTop) {
        if (busy == 0) {
        busy = 1;
        dragobjekt = element;
        dragx = posX - dragobjekt.offsetLeft + marginLeft;
        dragy = posY - dragobjekt.offsetTop + marginTop;
        }
        }
        (...)
        <someTag style="left:200px; top:0px; margin-left:100px; width:50px;"
        onclick="if(busy==0){javascript:dragstart(this,100,0);}
        else{javascript:dragstop();}" ></someTag>

        1. Lieber dropper,

          <someTag style="left:200px; top:0px; margin-left:100px; width:50px;"
          onclick="if(busy==0){javascript:dragstart(this,100,0);}
          else{javascript:dragstop();}" ></someTag>

          sowas willst Du ganz bestimmt 100...000000%ig nicht. Ich schwör's!

          Liebe Grüße,

          Felix Riesterer.

          --
          ie:% br:> fl:| va:) ls:[ fo:) rl:| n4:? de:> ss:| ch:? js:) mo:} zu:)
          1. Lieber dropper,

            <someTag style="left:200px; top:0px; margin-left:100px; width:50px;"
            onclick="if(busy==0){javascript:dragstart(this,100,0);}
            else{javascript:dragstop();}" ></someTag>

            sowas willst Du ganz bestimmt 100...000000%ig nicht. Ich schwör's!

            Hallo Felix,

            Hmmm, wieso nicht? Klappt wunderbar.
            Das styling war nur ein Beispiel, das natürlich - so, wie es da steht -
            wenig Sinn hat. Oder worauf genau beziehst Du Dich?
            Ich kenne HTML, CSS und js erst seit einigen Wochen und bin noch weit von
            solch hübschen Scripts wie das Deinige, zu dem Du mir freundlicherweise
            den Link gegeben hast, entfernt. Aber bin sehr dankbar für jeden Hinweis
            auf "schlechte" Code-Stellen in meinem script :-}

            Danke für Deine Antwort und Liebe Grüße, dropper

            1. Lieber dropper,

              Hmmm, wieso nicht? Klappt wunderbar.

              es ist "best practice", dass man JavaScript-relevante Sachen in einem <script>-Element (oder besser in einer ausgelagerten JavaScript-Datei) notiert. Dahinter steht der Ansatz, dass man Dokument-Struktur und Inhalt (also HTML-Code) und dynamische Logik bzw. "Verhalten" (also JavaScript) voneinander trennt. Das ist insbesondere dann sinnvoll, wenn man berücksichtigen will, wie Browser mit deaktiviertem JavaScript (oder solche Clients, die überhaupt keines unterstützen) mit dem Dokument umgehen werden.

              Anstatt nun in einem Element ein onclick-Attribut mit JavaScript-Code zu befüllen, um es mit einem dynamischen Verhalten auszurüsten, tut man das besser aus seinem JavaScript-Code heraus. Das hat dann den Vorteil, dass bei einer Veränderung des Dokumentinhalts keine JavaScript-Funktionalitäten mitgepflegt werden müssen, da sich das JavaScript seine Elemente selbst zurechtmodifiziert.

              Beispiel:
              HTML:

              <p id="author">  
                  Diese Seiten werden gepflegt von unserem Hausmeister  
                  <span class="name">Hans Theodor Michael Löffelholz</span>.  
              </p>
              

              JavaScript:

              function addClickEffectForAuthor () {  
                  var author = document.getElementById("author");  
                
                  if (author) {  
                      author.onclick = function () {  
                          alert("You needn't click the author. He is busy anyways!");  
                      }  
                  }  
              }
              

              Ich kenne HTML, CSS und js erst seit einigen Wochen und bin noch weit von
              solch hübschen Scripts wie das Deinige, zu dem Du mir freundlicherweise
              den Link gegeben hast, entfernt.

              Dafür hast Du Dir aber schon viel an Grundlagenwissen erarbeitet. Nix wie auf zum kleinen Lehrgang zum vernünftigen Schreiben eines JavaScripts!

              Liebe Grüße,

              Felix Riesterer.

              --
              ie:% br:> fl:| va:) ls:[ fo:) rl:| n4:? de:> ss:| ch:? js:) mo:} zu:)
              1. Hey Felix, vielen Dank für deine Antwort und das kleine Bsp.!!
                Es leuchtet mir nun durchaus ein.
                Dein Tutorial werde ich mir auf jeden Fall die Tage mal vorknöpfen, bin
                schon gespannt :-}
                Liebe Grüße,
                dropper

  2. Lieber dropper,

    in meinem Quiz-Script-Framework benutze ich Drag&Drop bei relativ positionierten Elementen. Kannst es Dir ja mal anschauen.

    Liebe Grüße,

    Felix Riesterer.

    --
    ie:% br:> fl:| va:) ls:[ fo:) rl:| n4:? de:> ss:| ch:? js:) mo:} zu:)
    1. Hey Felix,

      Danke für diesen Link!
      Habe da gerade mal den D&D-Code Deines Scriptes überflogen -
      schon ein paar neue Erkenntnisse/Ideen gewonnen, aber werde mir
      bei Gelegenheit mal etwas mehr Zeit nehmen und es ausführlicher
      begutachten - ist ja wirklich sehr schön kommentiert :}

      Lieben Gruß,
      dropper