Eric S: DOM - Position im DOMBaum ermitteln

Guten Morgern SelfHTMLer,

ich möchte Elemente verschieben im DOM-Baum, jeweils 1 hoch oder 1 runter, das klappt auch soweit, aber weil ich gleichzeitig ein 2D-Array mit verschieben muss, brauche ich die jeweilige Position im Baum:

Tree:
→DIV(Elternknoten)
 →DIV
 →DIV
 →DIV
 →...usw (Insgesamt 15 'UnterDIVs')

Jedes UnterDIV enthält daten aus dem Array
scma[1][x]
scma[2][x]
scma[3][x]
usw

Wenn die DIVs nach oben und unten verschoben werden, muss das jeweilige Array auch nach "oben" bzw "unten" verschoben werden, dazu muss ich aber wissen, welche Position es hat.

Hoffe JMD kann mir helfen

Greetings

  1. Hallo,

    ich möchte Elemente verschieben im DOM-Baum, jeweils 1 hoch oder 1 runter, das klappt auch soweit, aber weil ich gleichzeitig ein 2D-Array mit verschieben muss, brauche ich die jeweilige Position im Baum:

    diese Datenstruktur ist also ungünstig. Hast du schon mal daran gedacht, die zusätzlichen Daten nicht in einem getrennten Array vorzuhalten, sondern den DOM-Objekten direkt als zusätzliche Eigenschaft anzuhängen? Dann würden sie beim Umbauen des DOM-Baums automatisch mitwandern.

    Ciao,
     Martin

    --
    Wer keiner Fliege etwas zuleide tut, darf sich nicht über die Maden im Fleisch wundern.
    Selfcode: fo:) ch:{ rl:| br:< n4:( ie:| mo:| va:) de:] zu:) fl:{ ss:) ls:µ js:(
    1. Hallo,

      ich möchte Elemente verschieben im DOM-Baum, jeweils 1 hoch oder 1 runter, das klappt auch soweit, aber weil ich gleichzeitig ein 2D-Array mit verschieben muss, brauche ich die jeweilige Position im Baum:

      diese Datenstruktur ist also ungünstig. Hast du schon mal daran gedacht, die zusätzlichen Daten nicht in einem getrennten Array vorzuhalten, sondern den DOM-Objekten direkt als zusätzliche Eigenschaft anzuhängen? Dann würden sie beim Umbauen des DOM-Baums automatisch mitwandern.

      Ciao,
      Martin

      Hm, wie würde das denn aussehen? Zu bedenken ist aber (was ich vergessen habe zu erwähnen) in den Arrays sind jeweils 62 Zahlen + 3 Strings, sind also schon einige Werte =) Falls du setAttribute meinst, ich glaube das würde nicht ganz hinhauen, nicht bei so vielen Werten, sind ja insgesamt 65*15 Strings bzw Integer.

      Greetings

      1. Hi,

        Hallo,
        [...]
        Ciao,
        Martin
        Hm, wie würde das denn aussehen?

        zunächst bitte so, dass man nicht das komplette Vorgängerpsting zitiert (TOFU), sondern nur die notwendigen Abschnitte. Danke.

        Zu bedenken ist aber (was ich vergessen habe zu erwähnen) in den Arrays sind jeweils 62 Zahlen + 3 Strings, sind also schon einige Werte =)

        Das spielt keine Rolle. Es könnte auch eine Tabelle der Lottozahlen für Oberbayern bis Juni 2016 sein.

        Falls du setAttribute meinst, ...

        Nein. Bitte nicht von hinten durch die Brust ins Knie.

        // Wir bauen zunächst mal irgendein sco ("some complex object" zusammen:  
        var sco =  
         { ident:  'R04-F0600',                // ein Bezeichner  
           values: [2.15, 6.08, 2.81, 2.77],   // ein paar Messwerte oder sowas  
           foo:    800,                        // irgendein Zahlenwert  
           bar:    4.7E+06,                    // noch'n ziemlich großer Zahlenwert  
           baz:    'LC'                        // und ein Buchstabencode  
         };  
          
        // Nun konstruieren wir eine Referenz auf irgendein DOM-Objekt ...  
        var someDOMObject = document.getElementById('matrix').getElementByTagName('div')[4];  
          
        // ... und flanschen unser Daten-Objekt da dran:  
        someDOMObject.extra = sco;  
          
        // und -tadaa!- nun können wir die Daten als neue Eigenschaften des DOM-Objekts adressieren:  
        alert(someDOMObject.extra.ident);  
        alert(someDOMObject.extra.values[2]);
        

        Nicht dass das obige Beispiel irgendeinen Sinn ergibt; es soll nur das Prinzip verdeutlichen. Der Name "extra" für die zusätzlich angehängten Eigenschaften ist frei gewählt, er sollte nur nicht mit Eigenschaften kollidieren, die ein DOM-Node sowieso schon hat.

        Ich hoffe, ich habe damit etwas licht ins Dunkel gebracht.

        So long,
         Martin

        --
        Ein Patriot ist jemand, der bereit ist, sein Land gegen seine Regierung zu verteidigen.
        Selfcode: fo:) ch:{ rl:| br:< n4:( ie:| mo:| va:) de:] zu:) fl:{ ss:) ls:µ js:(
        1. Mahlzeit,

          Es könnte auch eine Tabelle der Lottozahlen für Oberbayern bis Juni 2016 sein.

          Hast du so ne Tabelle? Ich hab Interesse :D

          --
          42
          1. Es könnte auch eine Tabelle der Lottozahlen für Oberbayern bis Juni 2016 sein.

            Hast du so ne Tabelle? Ich hab Interesse :D

            JS machts möglich =P

            1. Mahlzeit,

              JS machts möglich =P

              Du meinst mit getElementsByYear('2016')?

              --
              42
        2. Ich hoffe, ich habe damit etwas licht ins Dunkel gebracht.

          Ja, hast Du, das kannte ich bisher noch nicht =) Ich glaube so werde ich es auch machen! Vielen Dank

    2. Hallo,

      Hast du schon mal daran gedacht, die zusätzlichen Daten nicht in einem getrennten Array vorzuhalten, sondern den DOM-Objekten direkt als zusätzliche Eigenschaft anzuhängen?

      Das ist möglich und sehr einfach, aber so löst man das heutzutage nicht mehr. Es ist problematisch ist, JavaScript-Objekte im DOM-Baum zu speichern. Das sind zwei Speicherbereiche, die verschiedener Garbage Collection unterliegen. Browser haben sich schon mehrfach daran verschluckt. Referenzen im DOM sollten sich auf Event-Handler beschränken. Die sind schon problematisch genug, da sie Closures sind.

      Wenn man Daten im DOM speichert, dann üblicherweise nicht direkt, sondern über eine UUID. So macht es jQuery.data. Am Element wird nur ein Attribut mit einer fortlaufenden Nummer gespeichert (expando genannt). In einem zentralen Hash werden die Daten unter diesem Key abgelegt. Das sorgt für eine Trennung von DOM- und JavaScript-Objekten. Siehe auch: http://curtistimson.net/Blog/Article/Understanding-jQuery-data()-storage

      Wenn man das verbessern möchte, dann würde ich zu einer MVC-Bibliothek raten, die Daten- und Darstellungslogik sauber trennt und per Data-Binding die Darstellung aktualisiert. Das kann z.B. Backbone oder CanJS sein. Dabei liegen die Daten als Models in einer Collection vor. Will man die Reihenfolge ändern, so ändert man sie in der Collection, denn diese ist maßgeblich. Die View überwacht Änderungen an der Collection and passt die Darstellung automatisch an, indem es z.B. die Elemente umsortiert. Die CollectionView von Chaplin macht das sehr effizient. Auch größere JavaScript-Frameworks wie Ember oder Angular arbeiten so.

      Mathias

  2. hi,

    Guten Morgern SelfHTMLer,

    ich möchte Elemente verschieben im DOM-Baum, jeweils 1 hoch oder 1 runter, das klappt auch soweit, aber weil ich gleichzeitig ein 2D-Array mit verschieben muss, brauche ich die jeweilige Position im Baum:

    Tree:
    →DIV(Elternknoten)
    →DIV
    →DIV
    →DIV
    →...usw (Insgesamt 15 'UnterDIVs')

    Jedes UnterDIV enthält daten aus dem Array
    scma[1][x]
    scma[2][x]
    scma[3][x]
    usw

    Wenn die DIVs nach oben und unten verschoben werden, muss das jeweilige Array auch nach "oben" bzw "unten" verschoben werden, dazu muss ich aber wissen, welche Position es hat.

    Hoffe JMD kann mir helfen

      
    <div id="parent">  
    <div>0</div>  
    <div>1</div>  
    <div>2</div>  
    <div>3</div>  
    </div>  
    <script>  
    [code lang=javascript]parent = document.getElementById("parent");  
    divs = parent.getElementsByTagName("div");  
    for (i=0; i<divs.length; i++) {  
    	divs[i].id = i;  
    	divs[i].onclick = function() {  
    		alert(this.id);  
    	}  
    }  
    
    ~~~</script>[/code]  
      
    Vielleicht hilft dir der Ansatz ja. Ich habe es nicht geschafft, das i zu alerten, ohne es als ID zu setzen, weil dann immer 4 alertet wird, denn das i läuft ja erst bis zum Ende durch.  
      
    Aber Du könntest beim Iterieren ja schauen, ob das aktuelle Div das korrekte ist.  
      
    mfg  
      
    tami
    
    1. hi,

      Hoffe JMD kann mir helfen

      <div id="parent">
      <div>0</div>
      <div>1</div>
      <div>2</div>
      <div>3</div>
      </div>
      <script>
      [code lang=javascript]parent = document.getElementById("parent");
      divs = parent.getElementsByTagName("div");
      for (i=0; i<divs.length; i++) {
      divs[i].id = i;
      divs[i].onclick = function() {
      alert(this.id);
      }
      }

      
      >   
      > Vielleicht hilft dir der Ansatz ja. Ich habe es nicht geschafft, das i zu alerten, ohne es als ID zu setzen, weil dann immer 4 alertet wird, denn das i läuft ja erst bis zum Ende durch.  
      >   
      > Aber Du könntest beim Iterieren ja schauen, ob das aktuelle Div das korrekte ist.  
        
      Martin hat bestimmt Recht, aber:  
        
      ~~~html
        
      <div id="parent">  
      <div>0</div>  
      <div>1</div>  
      <div>2</div>  
      <div>3</div>  
      </div>  
      <script>  
      [code lang=javascript]parent = document.getElementById("parent");  
      divs = parent.getElementsByTagName("div");  
      whereAmI = function () {  
      	for (i=0; i<divs.length; i++) {  
      		if (this == divs[i]) {  
      			alert("ich bin position" + i);  
      		}  
      	}  
      }  
      for (i=0; i<divs.length; i++) {  
      	divs[i].onclick = whereAmI;  
      }  
      
      ~~~</script>  
      [/code]  
        
      mfg  
        
      tami
      
    2. <div id="parent">
      <div>0</div>
      <div>1</div>
      <div>2</div>
      <div>3</div>
      </div>
      <script>
      [code lang=javascript]parent = document.getElementById("parent");
      divs = parent.getElementsByTagName("div");
      for (i=0; i<divs.length; i++) {
      divs[i].id = i;
      divs[i].onclick = function() {
      alert(this.id);
      }
      }

      
      >   
      > Vielleicht hilft dir der Ansatz ja. Ich habe es nicht geschafft, das i zu alerten, ohne es als ID zu setzen, weil dann immer 4 alertet wird, denn das i läuft ja erst bis zum Ende durch.  
      >   
      > Aber Du könntest beim Iterieren ja schauen, ob das aktuelle Div das korrekte ist.  
      >   
      > mfg  
      >   
      > tami  
        
      Hm, ok an getElementByTagName(TAG)[x] hatte ich garnicht gedacht ... ^^ werde das mal ausprobieren, danke!