obiwan1973: Ebenen mit der Maus hin- und herschieben

Hallo zusammen,

ich habe letztes Jahr schon einmal einen ähnlichen Beitrag gepostet:

http://forum.de.selfhtml.org/archiv/2013/11/t215659/#m1477263

Leider bin ich noch nicht weiter, ich hatte das Thema dann erst einmal verschoben.

Es geht um folgendes:
Ich möchte in meiner Anwendung auf "echte" JS-Popups verzichten und stattdessen Ebenen (DIVs) einsetzen, die wie Fenster aussehen.

Vom Prinzip her klappt alles.

Manche meiner Kollegen haben aber auf ihren PCs mit ihrem Browser (vorwiegend FF) Probleme, die Ebenen mit der Maus zu bewegen.
Es ruckelt alles ein bissel, und hin und wieder stoppt die Ebene sogar und will dann gar nicht mehr weiter.
Oder es geht so halb/halb, lässt sich schwer beschreiben.

Da heutzutage doch keiner mehr JS-Popups haben will, dachte ich, bin ich vielleicht nicht der einzige, der sich mit dem Thema beschäftigt.

Ich vermute, das Hauptproblem mit dem Bewegen meiner DIVs ist, dass von der DIV selber nicht viel Platz bleibt, um die Maus zu platzieren und das Ding zu verschieben. Die DIV ist nämlich vollgepackt mit Iframes etc. Bedeutet, es bleibt für die Maus eigentlich nur der blaue Rand oben, also ein Bereich, der nur ein paar cm hoch ist.

Ich möchte aber auf jeden Fall das Prinzip beibehalten, weil ich Popups hasse.

Frage: Hat sich schon jemand mit dem Thema befasst, kennt vielleicht Code-Beispiele?

Gruß

Thomas

  1. Om nah hoo pez nyeetz, obiwan1973!

    Aus deinem Betreff entnehme ich, du suchst eine ‚drag and drop‘-Lösung. http://aktuell.de.selfhtml.org/artikel/javascript/draganddrop/

    Was das mit Popups zu tun hat, erschließt sich mir nicht.

    Matthias

    --
    Der Unterschied zwischen Java und JavaScript ist größer als der zwischen voll und Vollzug.

    1. Hallo Matthias,

      schaue mir Deinen Link heute genauer an. Besten Dank für den Tipp.

      Du fragst wegen des Begriffs "Popup"? Naja, ich brauche dieses Drag&Drop Dingens eben, um Fensterchen zu kreieren, die so aussehen wie Fenster und auch so hin- und her-verschiebbar sein sollen, aber in Wirklichkeit sind es eben DIVs.

      Ich habe schon vor langer Zeit aufgehört, echte JS-Popups in meinén Intranet-Applikationen zu verwenden. Man kann die Dinger einfach kaum kontrollieren, die Browser entscheiden heute, was mit den Dingern geht und nicht. Und dann hat jeder einen Popup-Blocker.

      Melde mich wegen Deines Links und den anderen geposteten Links hier.

      Gruß

      Thomas

    2. Hallo Matthias,

      das ist so ziemlich derselbe JS-Code, den ich schon verwende.

      Mit diesem simplen Beispiel mit den beiden Kästen tut es ja prima, aber wenn Du eine DIV hast, die randvoll ist mit Objekten, dann will es einfach nicht. Es ruckelt brutal, bleibt dauern hängen usw. Ist einfach nicht schön.

      Muss wohl weiter schauen.

      Gruß

      Thomas

      1. Hallo,

        Es ruckelt brutal, bleibt dauern hängen usw. Ist einfach nicht schön.

        Des isch halt so.
        Der Browser muss das ja ständig neu rendern (Welcher? Welche Version? Alt?). Da wird dir nix anderes übrig bleiben, als auf HTML5 zu setzen und/oder zu hoffen, das JQuery für html5-fähige Browser auch das native Drag&Drop verwendet, was aber nichts nützt, wenn bei euch intern keine solchen benutzt werden.

        Viele Grüße
        Siri

        1. Hallo,

          Da wird dir nix anderes übrig bleiben, als auf HTML5 zu setzen und/oder zu hoffen, das JQuery für html5-fähige Browser auch das native Drag&Drop verwendet

          HTML5 Drag’n’Drop hat erstmal nichts mit dem Bewegen von Elementen mit der Maus zu tun. Es ist dafür gedacht, Elemente an ihrer Ursprungsposition aufzunehmen und in andere abzulegen. Das Element wird dabei standardmäßig visuell verdoppelt, und wenn es nicht in ein Drop-Target abgelegt wird, bewegt sich die Kopie wieder zur Ursprungsposition zurück.

          Man könnte mit den drag*-Events natürlich etwas basteln, sodass das Original ausgeblendet wird, der body ein Drop-Target ist und das Element beim Drop zur Mausposition bewegt wird. Das ist komplizierter als die klassische Lösung. Und performanter wird sie wahrscheinlich nicht sein, wieso auch? HTML5 Drag’n’Drop wurde nicht zur Verbesserung der Rendering-Performance geschaffen, sondern um die logische Verbindung zwischen verschiebbaren Element und Zielelement in JavaScript herzustellen.

          Um die Performance beim Verschieben von Elementen zu verbessern, kann man transform: translate() oder gar translate3d() verwenden. Im Gegensatz zu position: absolute mit top und left werden die CSS-Transformationen üblicherweise hardwarebeschleunigt. Es gibt auch verschiedene Hacks, um das Rendern auf dem Grafikchip zu erzwingen.

          http://www.paulirish.com/2012/why-moving-elements-with-translate-is-better-than-posabs-topleft/

          HTML5 hilft hier einem wenig weiter.

          Mathias

          1. Hallo,

            HTML5 Drag’n’Drop hat erstmal nichts mit dem Bewegen von Elementen mit der Maus zu tun. Es ist dafür gedacht, Elemente an ihrer Ursprungsposition aufzunehmen und in andere abzulegen. Das Element wird dabei standardmäßig visuell verdoppelt, und wenn es nicht in ein Drop-Target abgelegt wird, bewegt sich die Kopie wieder zur Ursprungsposition zurück.

            Spricht irgendwas dagegen, das Body-Element oder das HTML-Element als Drop-Target zu verwenden, die Zielposition abzurufen und das Drop-Element dorthin zu verschieben?
            Der obige Effekt (verdoppeln) würde (mich zumindest) nicht stören.

            Viele Grüße
            Siri

            1. Hallo,

              Spricht irgendwas dagegen, das Body-Element oder das HTML-Element als Drop-Target zu verwenden, die Zielposition abzurufen und das Drop-Element dorthin zu verschieben?

              Ich habe in meinem Posting zu beschreiben versucht, was dagegen spricht.

              Kurz zusammengefasst: Warum sollte man das versuchen? Das Problem war hier die Drag-Performance. Mit HTML5 Drag’n’Drop halst man sich eine komplexe API auf, die eigentlich für etwas anderes gedacht ist und nicht robust unterstützt wird. Ich will niemanden davon abhalten, die Technik hinsichtlich ihrer Performance zu evaluieren. Aber ich erhoffe mir davon nichts.

              Mathias

      2. Om nah hoo pez nyeetz, obiwan1973!

        das ist so ziemlich derselbe JS-Code, den ich schon verwende.

        Mit diesem simplen Beispiel mit den beiden Kästen tut es ja prima, aber wenn Du eine DIV hast, die randvoll ist mit Objekten, dann will es einfach nicht. Es ruckelt brutal, bleibt dauern hängen usw. Ist einfach nicht schön.

        Unter Umständen hilft es, dem angefassten Element eine Klasse "dragging" zu geben, vielleicht reicht auch die Pseudoklasse .active.

        Dann könntest du

        1. Versuch

        .dragging {  
          background-color: ivory;  
          border: 2px dotted lightblue;  
        }  
          
        .dragging * {  
          visibility: hidden;  
        }
        

        tun.

        Wenn das nicht reicht, würde ich die Abmessungen des Elements ermitteln und

        dies

        .dragging {  
          width:  /* ermittelte Größe */;  
          height: /* ermittelte Größe */;  
          background-color: ivory;  
          border: 2px dotted lightblue;  
        }  
          
        .dragging * {  
          display: none;  
        }
        

        versuchen.

        Dies sollte eigentlich eine deutliche Performance-Steigerung bewirken. Wenn nicht, musst du auf Molilys Lösungsvorschlag zurückgreifen.

        Matthias

        --
        Der Unterschied zwischen Java und JavaScript ist größer als der zwischen Tell und Teller.

  2. Wie wär es mit jquery drag & drop?

    Ein Popub bleibt jedoch ein Popup. Ob du das mit Fenstern, Tabs, Divs, Layern, Iframes oder mit Rexoblocks2000 machst ist total egal. Es ändert sich nichts daran das Popups (mit Werbung) einfach scheiße sind.

    Gruß
    Rexoblock2000 erfinder
    T-Rex

    1. Hallo Rexoblock2000 erfinder T-Rex,

      da gebe ich Dir voll recht - ich hasse Werbung auch. Aber es geht hier nicht um Werbung, sondern um eine Intranet-Anwendung für meine Firma. Also nix mit Werbung. Das ist - wenn Du so willst - eine kaufmännische Anwendung für eine Hand voll Leute :-)

      Also: Nicht aufregen. Bin auf Deiner Seite. Ich hasse Popups UND Werbung.

      Die Ebenen, die bei mir im Programm wie Fenster aussehen, haben denselben Zweck wie meine Iframes. Es geht einfach um Funktionalität, die Oberfläche einfach so zu modellieren, wie mein Chef sie haben möchte :-)

      Schaue mir Deinen Link mal an.

      Gruß

      Thomas

  3. Hallo,

    habe heute zwei Dinge ausprobiert.

    Einmal die jQuery-Methode:
    http://jqueryui.com/draggable/
    Hat nicht so viel gebracht, die Bewegung ist nicht besonders flüssig, es ruckelt doch sehr oft.

    #2 > CSS/translate():
    http://www.paulirish.com/2012/why-moving-elements-with-translate-is-better-than-posabs-topleft/
    Hat mich im ersten Augenblick umgehauen. Was geht denn da ab? :-)
    Die DIV düst umher, als wäre sie ein Formel 1 - Bolide. Wow!
    Ohne Ruckler. Siehe mein Code:

    ------------------------------------------------------------------------------------

      
      
    #div_email  
    {  
    	width		:	1190px;  
    	height		:	595px;  
    	left		:	0px;  
    	top		:	0px;  
    	margin		:	0px;  
    	padding-top	: 	0px;  
    	padding-bottom	:	0px;  
    	padding-left	:	0px;  
    	padding-right	:	0px;  
    	position        :	absolute;  
    	z-index		:	170;  
    	text-align	:	center;  
    	vertical-align	:	center;  
    	border-width	:	1px;  
    	border-color	:	#000000;  
    	border-style	:	solid;  
    	display		:	none;  
    	background	:	url(images/window_background_email.png);  
    }  
      
    
    

    ------------------------------------------------------------------------------------

      
      
      
       <div id="div_email" name="div_email" onmousedown="startDrag(this);">  
      
          ...  
      
       </div>  
      
    
    

    ------------------------------------------------------------------------------------

      
      
    <body onLoad="init()">  
      
       ...  
      
    </body>  
      
    
    

    ------------------------------------------------------------------------------------

      
      
      
    <SCRIPT LANGUAGE="JavaScript">  
    <!--  
      
    //----------------------------------------------------------  
      
    var objDrag = null;	// Element, über dem Maus bewegt wurde  
      
    var mouseX  = 0;	// X-Koordinate der Maus  
    var mouseY  = 0;	// Y-Koordinate der Maus  
      
    var offX    = 0;	// X-Offset des Elements, das geschoben werden soll  
    var offY    = 0;	// Y-Offset des Elements, das geschoben werden soll  
      
    //----------------------------------------------------------  
      
    // Initialisierungs-Funktion  
    function init()  
    {  
    	// Initialisierung der Überwachung der Events  
    	document.onmousemove = doDrag;  
    	document.onmouseup   = stopDrag;  
    }  
      
    //----------------------------------------------------------  
      
    // Wird aufgerufen, wenn die Maus über einer Box gedrückt  
    // wird  
    function startDrag(objElem)  
    {  
      // Objekt der globalen Variabel zuweisen -> hierdurch  
      // wird Bewegung möglich  
      objDrag = objElem;  
      //  
      // Offsets im zu bewegenden Element ermitteln  
      offX = mouseX - objDrag.offsetLeft;  
      offY = mouseY - objDrag.offsetTop;  
    }  
      
    //----------------------------------------------------------  
      
    // Wird ausgeführt, wenn die Maus bewegt wird  
    function doDrag(ereignis)  
    {  
      // Aktuelle Mauskoordinaten bei Mausbewegung ermitteln  
      mouseX = ereignis.pageX;  
      mouseY = ereignis.pageY;  
      //  
      // Wurde die Maus über einem Element gedrück, erfolgt  
      // eine Bewegung  
      if (objDrag != null)  
      {  
       // Element neue Koordinaten zuweisen  
       //		  
       objDrag.style["transform"] = "translate(" + (mouseX - offX) + "px, " + (mouseY - offY) + "px)";  
       //  
       //alert(mouseX + '/' + mouseY);  
      }  
    }  
      
    //----------------------------------------------------------  
      
    // Wird ausgeführt, wenn die Maustaste losgelassen wird  
    function stopDrag(ereignis)  
    {  
    	// Objekt löschen -> beim Bewegen der Maus wird  
    	// Element nicht mehr verschoben  
    	objDrag = null;  
    }  
      
    //----------------------------------------------------------  
      
    -->  
    </SCRIPT>  
    
    

    ------------------------------------------------------------------------------------

    Einziges Manko:

    Die DIV schwebt in sicherer Entfernung. Hängt wohl mit der Berechnung der neuen Koordinaten zusammen. Ich habe versucht, diese Berechnung zu modifizieren, damit Maus und DIV zusammenpassen, irgendwie. Aber diese Berechnung erfordert wohl einfach soviel Zeit, dass die Bewegung wieder ruckelig wird.

    Also: Das ist nicht die schlechteste Lösung. Besser als vorher - wo einem wegen der Ruckler die Haare ausfallen - ist es allemal.

    Ich zitiere noch Siri:
    "Spricht irgendwas dagegen, das Body-Element oder das HTML-Element als Drop-Target zu verwenden, die Zielposition abzurufen und das Drop-Element dorthin zu verschieben?
    Der obige Effekt (verdoppeln) würde (mich zumindest) nicht stören."

    Das würde ich auch noch gerne ausprobieren. Gestern habe ich genau das versucht, habe es aber nicht hinbekommen. Das wäre dann HTML5, oder? Ich glaube, es wurde versucht, die DIV zu verschieben, aber es hat nicht geklappt. Woran kann es gelegen haben? Daran, dass die DIV voll ist mit Iframes etc., also man könnte schon sagen, mit einer ganzen Mini-Applikation? Packt das das HTML5 nicht? Geht das nur, wenn in der DIV Text oder Bilder drin sind, oder so?

    So, wie das nämlich von der Optik her ausgesehen hat, als ich mit der Maus das ganze Gebilde verschieben wollte, irgendwie ist da alles ineinander verschwommen. Und dann: Das DROP hat gar nicht geklappt, also die Verschiebung zu "vollziehen". Das ging nicht. Es ist so, die DIV, die ich verschieben möchte, hat einen z-index ... und darunter liegt noch eine andere, praktisch eine Hintergrundebene, mit einem niedrigeren z-index. Ganz weit unten kommt der Body.

    Ich werde das nachher nochmal in Angriff nehmen, vielleicht habe ich ja dann mehr Glück.

    Gruß

    Thomas

    1. Hallo,

      Das würde ich auch noch gerne ausprobieren. Gestern habe ich genau das versucht, habe es aber nicht hinbekommen. Das wäre dann HTML5, oder? Ich glaube, es wurde versucht, die DIV zu verschieben, aber es hat nicht geklappt. Woran kann es gelegen haben? Daran, dass die DIV voll ist mit Iframes etc., also man könnte schon sagen, mit einer ganzen Mini-Applikation? Packt das das HTML5 nicht? Geht das nur, wenn in der DIV Text oder Bilder drin sind, oder so?

      Bitte vergiss den Begriff »HTML5« in dem Zusammenhang. Wenn man HTML5 nicht als Marketingwort benutzt, sondern als technischen Fachbegriff, so bezieht es sich auf die HTML5-Spezifikation. In der ist vieles spezifiziert, einschließlich Drag and Drop. Ob eine Technik inn HTML5 selbst oder in einer verwandten Spezifikation beschrieben ist, sagt über ihre Modernität oder Qualität nichts aus. HTML5 standardisiert so grundlegende JavaScript-Techniken zum Zugriff auf Dokumente, dass es nicht möglich ist, nicht HTML5 zu verwenden.

      Ja, iframes nehmen selbst Mausereignisse entgegen und können Dragging dadurch verhindern. Das Problem besteht bei sämtlichen Ereignissen, sie werden vom Dokument im iframe entgegen genommen und steigen nicht zu den Elementen im DOM des Dokuments darüber auf. Man kann hier natürlich tricksen, in man die Ereignisse schon im Dokument im iframe verarbeitet und nach oben durchreicht. Ich denke, das musst du bei deiner aktuellen Lösung schon tun. Jedenfalls ist es kein spezifisches Problem von HTML5 Drag and Drop.

      Mathias

  4. Hallo zusammen,

    ich habe es raus. Drag & Drop mit HTML5. Wahnsinn. Und es funktioniert. Nicht mit den alten Versionen vom Microsoft Dingsbums und auch nicht mit Apple Safari, aber wen juckt es.

    Die Anleitung, die funktioniert, gibt es hier. Und es ist nicht kompliziert:

    http://stackoverflow.com/questions/6230834/html5-drag-and-drop-anywhere-on-the-screen

    Wie gesagt, ich habe es hier getestet mit den neuesten Versionen von Mozilla, Opera und Chrome.

    Vermute mal, die neueren Versionen vom Explorer spielen auch mit.

    Möglicherweise habe ich auch vom Safari nicht die neueste Version auf meinem PC.

    Also: Bin happy! Schönen Dank an Euch alle.

    Gruß und ein schönes WE (habe morgen frei)

    Thomas