Christian Wichmann: Droptarget bei Drag&Drop ermitteln

Hallo,

mein Problem ist zwar schon einige Male im Forum aufgetaucht, aber eine zufriedenstellende Lösung habe ich im Archiv leider nicht gefunden.

Problem: Ich möchte - am besten auf Basis der in http://aktuell.de.selfhtml.org/tippstricks/dhtml/draganddrop/index.htm beschriebenen Lösung - ein Drag&Drop von verschiedenen <div>-Bereichen realisieren. Allerdings muss ich zusätzlich ermitteln können, auf welchem <div>-Element der Drag&Drop-Vorgang beendet wurde. Beispielhaft müsste eine alert()-Ausgabe wie "Objekt A wurde auf Objekt B fallen gelassen" möglich sein.

Hintergrund: Ich baue eine hierarchisch in Kategorien organisierte Artikeldatenbank (PHP/MySQL) auf. Als Übersicht habe ich eine dynamisch auf- und zuklappbare Kategorien-Artikel-Baumstruktur. Das funktioniert so weit alles ganz prima. Als i-Tüpfelchen wünsche ich mir jetzt noch, dass man Kategorien und Artikel per Drag&Drop in andere Kategorien verschieben kann. Anstelle der oben beschriebenen alert()-Ausgabe wird dann natürlich ein PHP-Skript aufgerufen, das die entsprechende Verschiebung in der Datenbank vornimmt.

Naiver Ansatz: Am einfachsten wäre es, das mouseup-Event nicht ausschließlich global zu behandeln, sondern derart, dass jedes <div>, auf das gedroppt werden kann, ein eigenes mouseup-Event hat. Da gibt es aber zwei neue Probleme: Erstens feuern dann sowohl das "lokale" als auch das "globale" mouseup-Event (was jedoch nicht so schlimm ist). Zweitens wird dummerweise das mouseup-Event immer von dem <div> ausgelöst, welches ich gedroppt habe, und nicht von dem, auf das ich gedroppt habe. Ich habe daraufhin den z-index des jeweils gedraggten <div> derart angepasst, dass es sich _hinter_ allen anderen <div>-Bereichen befindet. Die Hoffnung war, dass so auf jeden Fall das <div>, auf das gedroppt wurde, das mouseup-Event auslöst. Leider führte auch das nicht zum gewünschten Ergebnis.

Wenn mir jemand eine Lösung oder Lösungshinweise geben könnte, wäre ich sehr dankbar. Falls erforderlich, kann ich gerne noch ein ausführliches Codebeispiel posten.

  1. hi,

    Allerdings muss ich zusätzlich ermitteln können, auf welchem <div>-Element der Drag&Drop-Vorgang beendet wurde.

    welcher der beiden wäre das deiner meinung nach, wenn ich A hier "abtropfe"?
     _______    __________
    |    ___|__|__        |
    |   |   A     |       |
    |   |_________|       |
    |_______|  |__________|

    gruß,
    wahsaga

    --
    /voodoo.css:
    #GeorgeWBush { position:absolute; bottom:-6ft; }
    1. welcher der beiden wäre das deiner meinung nach, wenn ich A hier "abtropfe"?

      _______    __________
       |    ___|__|__        |
       |   |   A    _|       |
       |   |_______||       |
       |_______|  |__\_______|

      Das, über dem sich der Mauszeiger befindet (in diesem Fall das rechte Objekt). Sorry für den arg stilisierten ASCII-Pfeil ;-)

      1. welcher der beiden wäre das deiner meinung nach, wenn ich A hier "abtropfe"?
          _______    __________
        |    ___|__|__        |
        |   |   A    _|       |
        |   |_______||       |
        |_______|  |__\_______|

        Das, über dem sich der Mauszeiger befindet (in diesem Fall das rechte Objekt). Sorry für den arg stilisierten ASCII-Pfeil ;-)

        Ergänzung: Falls das einen Lösungsansatz vereinfacht, könnte man auch die linke obere Ecke oder den Mittelpunkt des gedroppten Objekt als maßgeblich betrachten. Irgendwie wird sich schon etwas Eindeutiges ergeben.

        1. Hi Christian!

          Dies scheint DAS Problem bei Drag&Drop im Browser zu sein!
          Ein Element unter dem Cursor mitzubewegen ist relativ einfach.
          Um aber zu Ermitteln, über welchem Objekt sich das gezogene gerade befindet könnte man die Koordinaten des Mauszeigers ermitteln und mit den Koordinaten der In Frage kommenden Targets abgleichen. Mit einer Schleife lässt sich dann ermitteln, ob der Cursor gerade innerhalb eines Target befindet und dieses dann z.B. mit einem dicken Rahmen versehen...

          Wenn es nicht zu viele mögliche Targets sind, könnte das klappen...
          Was hast du denn vor?

          Viele Grüße!

          Engywuck

          1. Hallo Engywuck,

            Dies scheint DAS Problem bei Drag&Drop im Browser zu sein!
            Ein Element unter dem Cursor mitzubewegen ist relativ einfach.
            Um aber zu Ermitteln, über welchem Objekt sich das gezogene gerade befindet könnte man die Koordinaten des Mauszeigers ermitteln und mit den Koordinaten der In Frage kommenden Targets abgleichen. Mit einer Schleife lässt sich dann ermitteln, ob der Cursor gerade innerhalb eines Target befindet und dieses dann z.B. mit einem dicken Rahmen versehen...

            Wenn es nicht zu viele mögliche Targets sind, könnte das klappen...
            Was hast du denn vor?

            Hab ich dich richtig verstanden? Du möchtest in mehreren verschachtelten For-Schleifen die Koordinaten deiner verschiebbaren Elemente während des Drag-Vorgangs in einem kurzzeitigen Intervall ständig miteienander abgleichen, um zu ermitteln, ob sie sich über einem erlaubten Drop-Target befinden?

            Also mein alter Rechner würde da sehr schnell schlapp machen.

            Ich arbeite bei meinem Zuordnungsspiel stattdessen mit einem Vokabel-Array. Daraus generiere ich einmal in der init()-Funktion zunächst die sichtbaren Target-Elemente, dann mit höherem Z-Index die beweglichen Elemente und schließlich mit einem nochmals höheren Z-Index die mit den optischen Targetelementen weitgehend deckungsgleichen unsichtbaren, aber sensitiven  Targetelemente.

            Darurch lassen sich die mobilen Elemente zwar über die sichtbaren Targets ziehen, gleichzeitig verschwinden sie aber unter den deckungsgleichen transparenten sensitiven Bereichen, sodass letztere durch den Überlagerungsvorgang selbst nichts an ihrer Sensitivität einbüßen.

            http://www.sprachlernspiele.de/dragdrop/alaHP/zuordnen2.html
            view-source:http://www.sprachlernspiele.de/dragdrop/alaHP/spiel2.js

            Gruß Gernot

            1. Also mein alter Rechner würde da sehr schnell schlapp machen.

              Ja, geht sicher nicht bei mehreren Targets... :-/

              Ich arbeite bei meinem Zuordnungsspiel stattdessen mit einem Vokabel-Array. Daraus generiere ich einmal in der init()-Funktion zunächst die sichtbaren Target-Elemente, dann mit höherem Z-Index die beweglichen Elemente und schließlich mit einem nochmals höheren Z-Index die mit den optischen Targetelementen weitgehend deckungsgleichen unsichtbaren, aber sensitiven  Targetelemente.

              Anmerkung:
              Dieses Verfahren stößt immer aber an Grenzen, sobald eines der Elternelemente eines Drop-Targets schon mit z-index arbeitet oder iframes eingesetzt werden.
              Solche Baumübersichten werden gerne aus iFrames aufgebaut, da man dann bei der Kommunikation mit dem Server (Maustruktur nachladen, neu laden, Datenbankbefehle) nicht das gesamte Dokument neu laden muss...

              Tipp:
              Beim Bundesfinale von Jugend forscht dieses Jahr haben 2 Studenten mit einem Webinterface zu Dateiverwaltung per Drag & Drop gewonnen.
              Die haben sicher Erfahrung mit Drag&Drop-Verfahren.

              Info: http://www.VirtOS.net
              Kontakt: mailto:H.Stahl@VirtOS.net (Einfach mal anfragen)

              Viel Erfolg!

              Engywuck

  2. Hallo Christian,

    Wenn mir jemand eine Lösung oder Lösungshinweise geben könnte, wäre ich sehr dankbar. Falls erforderlich, kann ich gerne noch ein ausführliches Codebeispiel posten.

    Für dein Problem empfehle ich dir die Lektüre des JavaScript-Workshops Kapitel 11 zu "erweitertem Event-Handling". Dort insbesondere die Übung 13.

    http://www.javascript-workshop.de/buch/11.html

    Die hat mir für meine Volkabel-Trainer-Studie nämlich auch sehr geholfen:

    http://www.sprachlernspiele.de/dragdrop/alaHP/oeffner.html

    Gruß Gernot