Lukas: Eingefüge Nodes verändern/löschen

Hallo.

Auch wenn ich eher denke, dass es sich um eine Waldproblem handelt, bei dem ich die Bäume nicht finde, verzweifle ich sei Tagen dran:

Ich hab ein kleines JavaScript Konzept geschrieben, bei dem es darum geht, HTML-Elemente mit JavaScript dynamisch miteinander grafisch zu verbinden. Ziel ist später eine Webapplikation zur Darstellung und Veränderrung von ER-Modellen. Das funktioniert auch soweit so gut.

Jetzt hab ich zudem noch ein Drag&Drop-Script hinzugefügt, was auch funktioniert. ebenso, dass, wenn die verschobenen HTML-Elemente sich nach dem Verschieben neu miteinander verbinden. Was NICHT funktioniert, ist allerdings, dass ich die "Alte" Linie wieder lösche, bzw. in meinem Script verändere (das ich sie verändere dient mir derzeit noch zu Lernzwecken).

Hier die HTML-Datei und das Script: (Erläuterrungen danach :) ) HTML:


<html>
    <head>
        <title>JavaScript-Test fŸr Verbindunglinien</title>
        <script type="text/javascript" src="js.js">
// JavaScript
        </script>
        <style type="text/css">
        /* CSS Styles */
            body { position:absolute; top:0px;left:0px;bottom:0px;right:0px; }
            #dbg {
                position:absolute;
                top:300px; left:10px;
                width:100px; height:200px;
                border: black solid 2px;

            }
            .divi {
                position:absolute;
                height:130px;
                border: red solid 2px;

            }

        </style>
    </head>
    <body id="body">
            <div class="divi" id="div_1" style="top:10; left:10px; width:100px;" onmousedown="movechoose('div_1')" onmouseup="moveend('div_1')" onmousemove="move('div_1')">
            <a href="javascript:klick('div_1')">#</a><br>
            DIV#1
        </div>
        <div class="divi" id="div_2" style="top:50; left:190px; width:150px;" onmousedown="movechoose('div_2')" onmouseup="moveend('div_2')" onmousemove="move('div_2')">
            <a href="javascript:klick('div_2')">#</a><br>
            DIV#2
        </div>
        <div class="divi" id="div_3" style="top:160; left:90px; width:100px;" onmousedown="movechoose('div_3')" onmouseup="moveend('div_3')" onmousemove="move('div_3')">
            <a href="javascript:klick('div_3')">#</a><br>
            DIV#3
        </div>
        <div class="divi" id="div_4" style="top:250; left:350px; width:50px;" onmousedown="movechoose('div_4')" onmouseup="moveend('div_4')" onmousemove="move('div_4')">
            <a href="javascript:klick('div_4')">#</a><br>
            DIV#4
        </div>
        <div id="dbg">
        </div>
    </body>
</htlm>

JavaScript:


// JavaScript
var klicked = 0;
var erstes = new Array();
erstes['id'] = "";
erstes['x'] = 0;
erstes['y'] = 0;
var zweites = new Array();
zweites['id'] = "";
zweites['x'] = 0;
zweites['y'] = 0;

var newdiv = new Array();

var verb = new Array();



function klick(wahl){
    dbg(wahl);
    var tmp = strip_px(document.getElementById("div_1").style.left);
    dbg(tmp);
    if(0 == klicked){
        erstes['id'] = wahl;
        erstes['x'] = strip_px(document.getElementById(wahl).style.left)
        erstes['y'] = strip_px(document.getElementById(wahl).style.top)
        klicked = 1;

    }else{
        if(erstes['id'] != wahl){
            if(true){    // Hier pruefen, ob das DIV ueberhaupt angeklickt werden darf.
                zweites['id'] = wahl;
                zweites['x'] = strip_px(document.getElementById(wahl).style.left);
                zweites['y'] = strip_px(document.getElementById(wahl).style.top);
                cons = new Array();
                cons['a'] = new Array();
                cons['a']['x'] = 0;
                cons['a']['y'] = 0;
                cons['b'] = new Array();
                cons['b']['x'] = 0;
                cons['b']['y'] = 0;
                var samex = false;
                if(erstes['x'] > zweites['x']){
                    // Erstes liegt rechts, also Tauschen.
                    var tmp = new Array();
                    tmp = erstes;
                    erstes = zweites;
                    zweites = tmp;
                }
                if(strip_px(document.getElementById(erstes['id']).style.width) > Math.abs(erstes['x'] - zweites['x'])){    // X herausfinden, um Connectorpunk zu bestimmen
                    // Liegen auf gleicher Breite
                    cons['a']['x'] = erstes['x']+strip_px(document.getElementById(erstes['id']).style.width)-25;
                    cons['a']['y'] = erstes['y']+25;
                    cons['b']['x'] = zweites['x']+strip_px(document.getElementById(zweites['id']).style.width)-25;
                    cons['b']['y'] = zweites['y']+25;

                    samex = true;
                }else{
                    cons['a']['x'] = erstes['x']+strip_px(document.getElementById(erstes['id']).style.width)-25;
                    cons['a']['y'] = erstes['y']+25;
                    cons['b']['x'] = zweites['x']+25;
                    cons['b']['y'] = zweites['y']+25;

                }

                if(erstes['y'] == zweites['y']){
                    new_strich('bla',cons['a']['x'],cons['a']['y'],Math.abs(cons['b']['x'] - cons['a']['x']),1);
                }else{
                    if(true == samex){

                        var s1_m = 0;
                        var s2_m = 0;

                        if(erstes['x'] < zweites['x']){
                            s1_m = zweites['x'] - erstes['x'];
                            s2_m = strip_px(document.getElementById(erstes['id']).style.width) - strip_px(document.getElementById(zweites['id']).style.width);
                        }else{
                            s2_m = erstes['x'] - zweites['x'];
                            s1_m = strip_px(document.getElementById(erstes['id']).style.width) - strip_px(document.getElementById(zweites['id']).style.width);
                        }
                        s1_x = cons['a']['x'];
                        s1_y = cons['a']['y'];
                        s1_l = 60 + s1_m;

                        s2_x = cons['b']['x'];
                        s2_y = cons['b']['y'];
                        s2_l = 60 + s2_m;

                        s3_y = s1_y;
                        if(s1_y > s2_y){
                            s3_y = s2_y;
                        }
                        s3_x = s1_x+60+s1_m;
                        s3_l = Math.abs(cons['b']['y']-cons['a']['y']);
                    }else{
                        var diff = (cons['b']['x'] - cons['a']['x'])/3;
                        dbg(diff);

                        s1_x = cons['a']['x'];
                        s1_y = cons['a']['y'];
                        s1_l = diff;

                        s2_x = cons['b']['x']-diff*2;
                        s2_y = cons['b']['y'];
                        s2_l = diff*2;

                        var senk = new Array();
                        s3_x = cons['a']['x']+diff;
                        s3_y = cons['a']['y'];
                        s3_l = cons['b']['y']-cons['a']['y'];
                        if(erstes['y'] > zweites['y']){
                            s3_x = cons['a']['x']+diff;
                            s3_y = cons['b']['y'];
                            s3_l = cons['a']['y']-cons['b']['y'];
                        }
                    }
                    new_strich('bla1',s1_x,s1_y,s1_l,1);
                    new_strich('bla2',s2_x,s2_y,s2_l,1);
                    new_strich('bla3',s3_x,s3_y,s3_l+3,0);
                    verb[erstes['id']] = zweites['id'];
                }
            }else{
                dbg("Dieses DIV steht nicht zu Auswahl");
            }
        }else{
            dbg("Du musst ein anderes als das erste DIV waehlen!");

        }
        // Klicked zurŸcksetzen
        klicked = 0;
    }


}

function new_strich(name,x,y,length,dir){

    newdiv[name] = document.createElement('div');
    newdiv[name].style.position = "absolute";
    newdiv[name].style.left = x;
    newdiv[name].style.top = y;
    newdiv[name].style.backgroundColor = '#123456';
    if(1 == dir){
        newdiv[name].style.width = length;
        newdiv[name].style.height = '3px';
    }else{
        newdiv[name].style.height = length;
        newdiv[name].style.width = '3px';
    }
    document.getElementById('body').appendChild(newdiv[name]);
    return newdiv[name];
}

function strip_px(vari){
    var ret = vari.substr(0,(vari.length-2));
    return parseInt(ret);
}

function dbg(vari){
    document.getElementById('dbg').innerHTML = vari + '<br>' + document.getElementById('dbg').innerHTML;
}

var tmpposx = 0;
var tmpposy = 0;
var tmpklcx = 0;
var tmpklcy = 0;
var ifmove = 0;

function movechoose(divi){
//    blablubb = window.event;
    tmpklcx = window.event.clientX;
    tmpklcy = window.event.clientY;
    // Abweichung eintragen

    tmpposx = strip_px(document.getElementById(divi).style.left) - tmpklcx;
    tmpposy = strip_px(document.getElementById(divi).style.top) - tmpklcy;

    ifmove = 1;
}

function move(divi){
    if(1 == ifmove){
        document.getElementById(divi).style.left = window.event.clientX + tmpposx;
        document.getElementById(divi).style.top = window.event.clientY + tmpposy;
    }
}

function moveend(divi){
    tmpposx = 0;
    tmpposy = 0;
    tmpklcx = 0;
    tmpklcy = 0;
    ifmove = 0;
    if(newdiv['bla1']){
        newdiv['bla1'].style.border = "red solid 5px;";
        document.getElementById('body').appendChild(newdiv['bla1']);

    }
    for(var key in verb){
        if(divi == key || divi == verb[key]){
            klick(key);
            klick(verb[key]);

        }
    }
}

Ich denke, das HTML dürfte selberklärend sein. Kernpunkt sind die vier DIVs der CLASS "divi"

Beim JavaScript ist die Funktion new_strich() relevant, die neue Nodes in das Dokument einbindet, und unter den Indizies "bla1", "bla2", bla3" im globalen Array "newdiv[]" hinterlegt (zumindest so mein Gedanke, kann ja auch sein, dass da der Hase begraben liegt)

Wo ich allerdings den Knackpunkt vermute ist in der Funktion moveend() (die letzte im JS-Part) und zwar folgender Part:


    if(newdiv['bla1']){
        newdiv['bla1'].style.border = "red solid 5px;";
        document.getElementById('body').appendChild(newdiv['bla1']);
    }

Gewünscht ist, dass, sofern schon ein Objekt "bla1" vorhanden ist, dieses einen dicken roten Rahmen bekommt. Aber genau das passiert nicht.

Um das mal zu testen, geht man folgendermaßen vor: (Mal vorrausgesetzt, dass man alles schon in Dateien hat (JavaScript-Datei muss js.js heißen und im selben Ordner wie die HTML-Datei liegen). Man klickt auf zwei verschiedene verlinkte Rauten, was eine grafische Verbindung zwischen den Boxen herstellt. Nun schiebt man eine der verbundenen Boxen mit gedrückter Mausstaste woanders hin. Es erscheint eine zweite Verbinungslinie. Aber die erste ist immer noch unverändert da.

Mein System: OSX 4.9 mit Safari, aber auch unter FireFox tritt das selbe Problem auf.

Fehlermeldungen bekomme ich leider keine :(

Bitte beachtet, dass es sich hierbei noch nicht um ein fertiges Script handelt, sondern nur um ein Konzept, um herauszufinden, wie sich was realisieren lässt. Anspruch auf Schönheit und vollkommene Dynamik besteht derzeit noch nicht :)

lieben gruß Lukas

  1. hi,

    Um das mal zu testen, geht man folgendermaßen vor:
    (Mal vorrausgesetzt, dass man alles schon in Dateien hat (JavaScript-Datei muss js.js heißen und im selben Ordner wie die HTML-Datei liegen).

    Man (ich) setzt voraus, dass das als fertig ausprobierbares Online-Beispiel bereitgestellt wird.

    gruß,
    wahsaga

    --
    /voodoo.css:
    #GeorgeWBush { position:absolute; bottom:-6ft; }
    1. hi,

      Um das mal zu testen, geht man folgendermaßen vor:
      (Mal vorrausgesetzt, dass man alles schon in Dateien hat (JavaScript-Datei muss js.js heißen und im selben Ordner wie die HTML-Datei liegen).

      Man (ich) setzt voraus, dass das als fertig ausprobierbares Online-Beispiel bereitgestellt wird.

      gruß,
      wahsaga

      Hab ich auch lieber, ist mir aber mangels Webspace nicht so einfach möglich.
      Aber gut, hab irgendwo noch ne Tripod-Account, auf den ich das heute abend mal hochladen werde :)

  2. Hallo,

    ich halte ja nicht soviel davon, wenn mit "foo" und "bar" hantiert wird, und bla und blubb sind auch nicht besser ....
    ich kann mir nix drunter vorstellen, und dein Script auch nicht

      
      
    
    > function moveend(divi){  
    >     tmpposx = 0;  
    >     tmpposy = 0;  
    >     tmpklcx = 0;  
    >     tmpklcy = 0;  
    >     ifmove = 0;  
    >     if(newdiv['bla1']){  
      
               alert("komme ich hier hin?") // auch nach der Korrektur, komme ich hier nicht hin?  
      
    
    >         newdiv['bla1'].style.border = "red solid 5px;";  
    >         document.getElementById('body').appendChild(newdiv['bla1']);  
    >   
    >     }  
    
      ...  
    
    > }  
    
    

    Gruß plan_B

    --
         *®*´¯`·.¸¸.·
    1. Hallo,

      ich halte ja nicht soviel davon, wenn mit "foo" und "bar" hantiert wird, und bla und blubb sind auch nicht besser ....
      ich kann mir nix drunter vorstellen, und dein Script auch nicht

      inzwischen habe ich dein "bla1" doch noch gefunden, aber wennn ich's richtig verstanden habe, sollen die 3 bla's deine Verbindungslinien sein.

      Die Verbindungslinien soll neu_strich() bearbeiten? dann sollten dort auch die alten Verbindungslinien gelöscht werden:

        
      function new_strich(name,x,y,length,dir){  
        
        if (newdiv[name] ) {  // Linie vorhanden ?  
         var od=newdiv[name];  // old div;  
         od.parentNode.removeChild(od);  
         }  
        
          newdiv[name] = document.createElement('div');  // neue Linie  
          ...  
        
         }  
        
      function moveend(divi){  
          tmpposx = 0;  
          tmpposy = 0;  
          tmpklcx = 0;  
          tmpklcy = 0;  
          ifmove = 0;  
          divi.style.borderWidth = "5px";  
        
          for(var key in verb){  
              if(divi.id == key || divi.id == verb[key]){  
                  klick(key);  
                  klick(verb[key]);  
              }  
          }  
      }  
      
      

      Unter der Voraussetzung
      <div id="div_1" ... onmouseup="moveend(this)">
      funktioniert nun auch der dicke Rahmen.

      Nehme mal an, s.ä. sollte es aussehen - Kompliment: gut gemacht!

      noch ein Tipp: wenn du generell mit den Referenzen auf die HTML-Objekte(divs) arbeitest, sparst du dir die lästigen Aufrufe document.getElementById()

      Gruß plan_B

      --
           *®*´¯`·.¸¸.·
  3. Hallo,

    <div class="divi" id="div_1" style="top:10; left:10px; width:100px;" onmousedown="movechoose('div_1')" onmouseup="moveend('div_1')" onmousemove="move('div_1')">
                <a href="javascript:klick('div_1')">#</a><br>
                DIV#1
            </div>

      
    mach es dir einfacher:  
      
    ~~~html
      
    <div class="divi" id="div_1" style="top:10px; left:10px; width:100px;"  
     onmousedown="movechoose(this)" onmouseup="moveend(this)" onmousemove="move(this)">  
    <a href="javascript:klick('div_1')">#</a><br>DIV#1  
    </div>  
    
    

    vergiss nicht die "px" bei "top:10px;"

    und arbeite mit den div-Objekten, z.B.

      
    function moveend(divi){  
     alert("divi "+divi.id)  
        tmpposx = 0;  
        tmpposy = 0;  
        tmpklcx = 0;  
        tmpklcy = 0;  
        ifmove = 0;  
        divi.style.borderWidth = "5px";  
    //        document.getElementById('body').appendChild(divi);  
      
         for(var key in verb){  
            if(divi == key || divi.id == verb[key]){  
                klick(key);  
                klick(verb[key]);  
      
            }  
        }  
    }  
    
    

    die Bordereigenschaften müssen wohl einzeln gesetzt werden ...

    wenn du "verb" als new Object definierst, wird deine Abfrage einfacher

    if (verb[divi.id]) {
       klick(divi.id)
      }

    Gruß plan_B

    --
         *®*´¯`·.¸¸.·