Patrick Andrieu: Hilfe zum Verständnis

Hallo alle!

Im body einer Website befinden sich vier Elemente mit IDs, die sich nur durch eine Zahl unterscheiden, etwa so:

id="elem_1", id="elem_2", usw.

In einer Funktion, die beim Laden aufgerufen wird, "get" ich sie mit Hilfe einer Schleife wie folgt (in diesem Fall weiß ich, dass es 4 Elemente sind, welche diese ID-Struktur haben):

  
  for (var i=1;i<=4;i++) {  
    dc.getElementById('elem_'+i).style.visibility="visible";  
  }  

Soweit so gut, alle versteckte Elemente (hatten visibility:hidden) werden angezeigt.

Nächster Schritt:

  
  for (var i=1;i<=4;i++) {  
    dc.getElementById('elem_'+i).onclick = alert('elem_'+i);  
  }  

Hier poppen beim Aufruf der Seite nacheinander 4 Alertboxen mit als respektive+m Inhalt elem_1, elem_2 usw., soweit auch korrekt, aber erste Frage:

Warum gehen die Boxen beim Aufruf der Seite auf, da hat doch nirgends ein Klick stattgefunden? Zwar wird die Funktion beim Laden aufgerufen, aber ich habe doch onclik definiert?

Wieder nächster Schritt:

  
  for (var i=1;i<=4;i++) {  
    dc.getElementById('elem_'+i).style.visibility="visible";  
    dc.getElementById('elem_'+i).onclick = function() { alert('elem_'+i); };  
  }  

Die vier Elemente werden sichtbar gemacht. Nur, egal welchen ich anklicke, erhalte ich im Alert elem_5, also elem_ und der höchstmögliche Wert von i nach Durchlauf der Schleife (4+1). Ich hätte hier eher erwartet, dass beim Klick auf einem Element die entsprechende ID im Alert ausgegeben wird. Daher zweite Frage:

Wie kann ich erreichen, dass beim Klick auf einem der vier Elemente eine Funktion (die ich hier für's Beispiel durch die alert() ersetzt habe) aufrufen, die auf den entsprechenden Wert von i angewiesen ist?

Viele Grüße aus Frankfurt/Main,
Patrick

--

_ - jenseits vom delirium - _
<hatehtehpehdoppelpunktslashslashwehwehwehpunktatomicminuseggspunktcomslash>
  1. Hallo Patrick,

    Nächster Schritt:

    for (var i=1;i<=4;i++) {
        dc.getElementById('elem_'+i).onclick = alert('elem_'+i);
      }

    
    >   
    > Hier poppen beim Aufruf der Seite nacheinander 4 Alertboxen mit als respektive+m Inhalt elem\_1, elem\_2 usw., soweit auch korrekt, aber erste Frage:  
    >   
    > Warum gehen die Boxen beim Aufruf der Seite auf, da hat doch nirgends ein Klick stattgefunden? Zwar wird die Funktion beim Laden aufgerufen, aber ich habe doch onclik definiert?  
      
    Ja - du hast definiert, dass dem Attribut "onclick" der Rückgabewert der Funktion alert('elem\_'+i) zugewiesen werden soll.  
    Ich nehme an, du meintest (ungetestet):  
    ~~~javascript
      
    for (var i=1;i<=4;i++) {  
      dc.getElementById('elem_'+i).onclick = 'alert(elem_'+i+')';  
    }
    

    Grüße

    Marc Reichelt || http://www.marcreichelt.de/

    --
    Linux is like a wigwam - no windows, no gates and an Apache inside!
    Selfcode: ie:{ fl:| br:> va:} ls:< fo:} rl:( n4:( ss:) de:> js:| ch:? sh:| mo:) zu:)
    1. Hallo Marc,

      Ja - du hast definiert, dass dem Attribut "onclick" der Rückgabewert der Funktion alert('elem_'+i) zugewiesen werden soll.
      Ich nehme an, du meintest (ungetestet):

      for (var i=1;i<=4;i++) {
        dc.getElementById('elem_'+i).onclick = 'alert(elem_'+i+')';
      }

        
      Ich nehme, ebenso ungetestet an, Patrick meinte:  
      ~~~javascript
        
      for (var i=1;i<=4;i++) {  
        with(dc.getElementById('elem_'+i) {  
           style.visibility = "visible";  
           onclick = function () { alert(this.id); };  
        }  
      }
      

      Gruß Gernot

    2. Hallo Marc und Gernot!

      Ich antworte hier nur einmal, um nicht zwei Postings absetzen zu müssen.

      for (var i=1;i<=4;i++) {
        dc.getElementById('elem_'+i).onclick = 'alert(elem_'+i+')';
      }

        
      Ok, hier kommen keine Alerts beim Aufruf, dafür passiert nichts beim Klicken auf die Elemente. Bei Gernots Vorschlag:  
        
      
      > ~~~javascript
        
      
      > for (var i=1;i<=4;i++) {  
      >   with(dc.getElementById('elem_'+i) {  
      >      style.visibility = "visible";  
      >      onclick = function () { alert(this.id); };  
      >   }  
      > }
      
      

      Hier kommt undefined raus. Aber this.id bringt mich in der Tat weiter (zumindest im Beispiel):

        
        for (var i=1;i<=4;i++) {  
          dc.getElementById('elem_'+i).style.visibility="visible";  
          dc.getElementById('elem_'+i).onclick = function() {  alert(this.id); };  
        }  
      
      

      Hier wird beim Klicken die ID des jeweils angeklickten Elements 'rausgegeben.

      Aber damit man mir die Erklärung bestätigt. Mein drittes Beispiel im Originalbeitrag kann nicht das von mir erst gedachte Ergebnis liefern, weil die Scheife bereits zu Ende durchgelaufen ist, bevor das Alert aufgerufen wird? Ist es so richtig?

      Was ich versuchte zu erreichen ist folgendes:

      Im Quelltex sind $x Elemente, alle mit visibility:hidden definiert und mit IDs wie beschrieben. Im Dokument verteilt sind entsprechende Links definiert (a-Elemente) - für den Aufruf.

      Bisher sieht es so aus:
      <a href="nojavascript_0.html" onclick="show('elem_0');">Zeig's mir</a>
      text text text
      <a href="nojavascript_1.html" onclick="show('elem_1');">Zeig's mir</a>

      Jetzt wollte ich mir die onclicks in den a-Tags sparen und alles in einer Funktion packen, die ich mir so gedacht hatte (nach dem die Links eine Klasse verpasst bekommen haben):
      <a href="nojavascript_0.html" class="klasse">Zeig's mir</a>
      text text text
      <a href="nojavascript_1.html" class="klasse">Zeig's mir</a>

      for (var i=0;i<getElementsByClassName(document, "a", "klasse").length;i++) {
        getElementsByClassName(document, "a", "klasse")[i].onclick = function() { show('elem_'+i);}
      }

      was, wie eben im ersten Beitrag mit alert() gezeigt, nichts bringt, da i in der Funktion den letztmöglichen Wert bekommt. "getElementsByClassName" ist eine der vielen im Web beschriebenen Simulation einer nicht existierenden Methode des document-Objekts.

      Jetzt könnte ich den Links zusätzlich eine ID verpassen (z.B. jeder Link hätte eine ID in der Form id="elem_0_link" usw.). Dann in der Function bei onclick diese zerpflücken (_link entfernen) und den Reststring (hier wäre das: elem_0) in eine Variable param speichern, die dann der Parameter für show ist:

      onclick = function () {
      zerpflücke mir this.id
      param = erster Teil von this.id
      show(param);
      }

      Erscheint mir aber ein Riesenaufwand... vielleicht gibt mir jemand ein Denkschubs für eine elegantere Lösung?

      Viele Grüße aus Frankfurt/Main,
      Patrick

      --

      _ - jenseits vom delirium - _
      <hatehtehpehdoppelpunktslashslashwehwehwehpunktatomicminuseggspunktcomslash>
      1. Hallo Patrick,

        den bloßen Index könntest du dir ja auch in einer als Eigenschaft an das HTML-Objekt gebundenen Variablen speichern.

          
        for (var i=1;i<=4;i++) {  
          with(dc.getElementById('elem_'+i) {  
             style.visibility = "visible";  
             indx = i;  
             onclick = function () { alert(this.indx); };  
          }  
        }
        

        Gruß Gernot

        1. Hallo Gernot!

          den bloßen Index könntest du dir ja auch in einer als Eigenschaft an das HTML-Objekt gebundenen Variablen speichern.

          for (var i=1;i<=4;i++) {
            with(dc.getElementById('elem_'+i) {
               style.visibility = "visible";
               indx = i;
               onclick = function () { alert(this.indx); };
            }
          }

            
          Hier kommt zwar keine Fehlermeldung (wenn man die fehlende Klammer bei: with(dc.getElementById('elem\_'+i))<< hier einsetzt), allerdings liefert jedes Alert beim Klick auf je einem Element immer nur "4" - also den letzte Scheifendurchlaufswert.  
            
          Viele Grüße aus Frankfurt/Main,  
          Patrick
          
          -- 
          ![](http://www.atomic-eggs.com/clubsig.gif)  
            
          \_ - jenseits vom delirium - \_  
            
          <hatehtehpehdoppelpunktslashslashwehwehwehpunktatomicminuseggspunktcomslash>
          
      2. ich hatte das ganz übersehen hier:

        for (var i=0;i<getElementsByClassName(document, "a", "klasse").length;i++) {
          getElementsByClassName(document, "a", "klasse")[i].onclick = function() { show('elem_'+i);}
        }

        ...

        Jetzt könnte ich den Links zusätzlich eine ID verpassen (z.B. jeder Link hätte eine ID in der Form id="elem_0_link" usw.). Dann in der Function bei onclick diese zerpflücken (_link entfernen) und den Reststring (hier wäre das: elem_0) in eine Variable param speichern, die dann der Parameter für show ist:

        Du musst nicht ID verwenden, du kannst dem Objekt eine x-beliebige Eigenschaft gegen.
        .

          
        var elements = getElementsByClassName(document, "a", "klasse");  
          
        for (var i = 0; i < elements.length; i++)  
        {  
        elements[i].show = 'elem_' + i;  
        elements[i].onclick = function()  
        {  
         show(this.show);  
        };  
        }  
        
        

        Struppi.

        --
        Javascript ist toll (Perl auch!)
        1. Hallo Struppi!

          var elements = getElementsByClassName(document, "a", "klasse");

          for (var i = 0; i < elements.length; i++)
          {
          elements[i].show = 'elem_' + i;
          elements[i].onclick = function()
          {
          show(this.show);
          };
          }

            
            
          Danke Struppi, das bringt mich schon ein ganzes Stück weiter!  
            
          Viele Grüße aus Frankfurt/Main,  
          Patrick
          
          -- 
          ![](http://www.atomic-eggs.com/clubsig.gif)  
            
          \_ - jenseits vom delirium - \_  
            
          <hatehtehpehdoppelpunktslashslashwehwehwehpunktatomicminuseggspunktcomslash>
          
  2. Warum gehen die Boxen beim Aufruf der Seite auf, da hat doch nirgends ein Klick stattgefunden? Zwar wird die Funktion beim Laden aufgerufen, aber ich habe doch onclik definiert?

    Das ist geklärt.

    Wieder nächster Schritt:

    for (var i=1;i<=4;i++) {
        dc.getElementById('elem_'+i).style.visibility="visible";
        dc.getElementById('elem_'+i).onclick = function() { alert('elem_'+i); };
      }

    
    >   
    > Die vier Elemente werden sichtbar gemacht. Nur, egal welchen ich anklicke, erhalte ich im Alert elem\_5, also elem\_ und der höchstmögliche Wert von i nach Durchlauf der Schleife (4+1). Ich hätte hier eher erwartet, dass beim Klick auf einem Element die entsprechende ID im Alert ausgegeben wird.  
      
    Nein, du erzeugst hier keine neue Funktion, sondern es ist eine Funktion die den Wert des letzten Aufrufs hat.  
      
    
    > Wie kann ich erreichen, dass beim Klick auf einem der vier Elemente eine Funktion (die ich hier für's Beispiel durch die alert() ersetzt habe) aufrufen, die auf den entsprechenden Wert von i angewiesen ist?  
      
    Bist du sicher dass du dort das i brauchst?  
    Innerhald der Funktion kannst du ja bereits auf this zugreifen und benötigst die ID nicht um das Element zu ermitteln.  
      
    Wenn du meinst es geht nicht anders, dann kannst du mit new Funktion eine neue Funktion erzeugen.  
      
    ~~~javascript
      
      for (var i=1;i<=4;i++) {  
         dc.getElementById('elem_'+i).style.visibility="visible";  
         dc.getElementById('elem_'+i).onclick = new Function("alert('elem_'" + i + ')');  
    }  
    }  
    
    

    Struppi.

    --
    Javascript ist toll (Perl auch!)
    1. Hallo Struppi!

      sondern es ist eine Funktion die den Wert des letzten Aufrufs hat.

      OK.

      Bist du sicher dass du dort das i brauchst?

      Ja, siehe mein anderes Posting. Der Fall ist etwas anders gelagert, diese erste Beispiele waren nur vereinfacht.

      Wenn du meinst es geht nicht anders, dann kannst du mit new Funktion eine neue Funktion erzeugen.

      for (var i=1;i<=4;i++) {
           dc.getElementById('elem_'+i).style.visibility="visible";
           dc.getElementById('elem_'+i).onclick = new Function("alert('elem_'" + i + ')');
      }
      }

        
      Zuerst wurde eine Klammer } zuviel bemängelt, wenn ich sie entferne, erhalte ich diese Meldung:  
        
      Error: missing ) after argument list  
      alert('elem\_'1 )  
                    ^  
        
      Viele Grüße aus Frankfurt/Main,  
      Patrick
      
      -- 
      ![](http://www.atomic-eggs.com/clubsig.gif)  
        
      \_ - jenseits vom delirium - \_  
        
      <hatehtehpehdoppelpunktslashslashwehwehwehpunktatomicminuseggspunktcomslash>
      
      1. for (var i=1;i<=4;i++) {
             dc.getElementById('elem_'+i).style.visibility="visible";
             dc.getElementById('elem_'+i).onclick = new Function("alert('elem_'" + i + ')');
        }
        }

        
        >   
        > Zuerst wurde eine Klammer } zuviel bemängelt, wenn ich sie entferne, erhalte ich diese Meldung:  
        >   
        > Error: missing ) after argument list  
        > alert('elem\_'1 )  
          
        da fehlt noch ein Pluszeichen  
          
        ~~~javascript
          
        for (var i=1;i<=4;i++)  
        {  
        dc.getElementById('elem_'+i).style.visibility="visible";  
        dc.getElementById('elem_'+i).onclick = new Function("alert('elem_' + " + i + ')');  
        }  
        
        

        Struppi.

        --
        Javascript ist toll (Perl auch!)
        1. Hallo Struppi!

          da fehlt noch ein Pluszeichen

          for (var i=1;i<=4;i++)
          {
          dc.getElementById('elem_'+i).style.visibility="visible";
          dc.getElementById('elem_'+i).onclick = new Function("alert('elem_' + " + i + ')');
          }

            
          Ja, die Alerts liefern die korrekte ID. Allerdings hast Du mir da etwas serviert, was ich auch verstehen möchte. Warum muss es so ausgeanführungszeichet werden - new Function("alert('elem\_' + " + i + ")"); halte ich übrigens für übersichtlicher -? Kann ich dann auch new Function(was\_drin) { function() {...;}; } schreiben?  
            
            
          Viele Grüße aus Frankfurt/Main,  
          Patrick
          
          -- 
          ![](http://www.atomic-eggs.com/clubsig.gif)  
            
          \_ - jenseits vom delirium - \_  
            
          <hatehtehpehdoppelpunktslashslashwehwehwehpunktatomicminuseggspunktcomslash>
          
  3. Hallo Patrick!

    Ich greife mal eines Deiner Beispiele auf:

    Wieder nächster Schritt:

    for (var i=1;i<=4;i++) {
        dc.getElementById('elem_'+i).style.visibility="visible";
        dc.getElementById('elem_'+i).onclick = function() { alert('elem_'+i); };
      }

      
    Meine Vermutung ist, dass hier nicht klar definiert ist,  
    ob der Index i gemeint ist, während ich mich in  
    der Schleife befinde oder der Index i, nachdem ich mich hinter der Schleife befinde (bzw. nicht \_ich\_ sondern der Javascript-Interpreter). Ich könnte mir auch vorstellen,  
    dass dieses Ergebnis je nach Browser / Javascript-Implementation  
    unterschiedlich ausfällt.  
      
    Wie funktioniert es, wenn Du Dir die Befehle erst  
    als String zusammenbastelst und darauf dann die  
    eval()-Funktion loslässt:  
      
    ~~~javascript
      
      for(var i=1; i<=4; ++i) {  
        var s = "dc.getElementById('elem_" + i + "').style.visibility = 'visible'";  
        eval(s);  
        s = "dc.getElementById('elem_" + i + "').onclick = function() { alert('elem_" + i + "'); };";  
        eval(s);  
      }  
    
    

    (Disclaimer: Das ganze ist ungetestet und kann Syntaxfehler enthalten...)

    Viele Grüße

    Andreas

    1. Hallo Andreas!

      (Disclaimer: Das ganze ist ungetestet und kann Syntaxfehler enthalten...)

      Nein, ich konnte es ohne Fehlermeldung testen, es wurden auch die richtigen Werte ausgegeben.

      Bist Du nicht alteeeeer? ;)

      Viele Grüße aus Frankfurt/Main,
      Patrick

      --

      _ - jenseits vom delirium - _
      <hatehtehpehdoppelpunktslashslashwehwehwehpunktatomicminuseggspunktcomslash>
      1. Bist Du nicht alteeeeer? ;)

        Huch - erwischt ;-)

        Viele Grüße aus Braunschweig

        Andreas

        1. Hallo Andreas!

          Bist Du nicht alteeeeer? ;)
          Huch - erwischt ;-)

          Hihi, ich konnte mich noch an einem Namenswechsel erinnern, aber nicht mehr genau an den neuen Namen... Hinzu kommt, dass ich fast 4 Jahren hier nicht mehr - oder nur selten - gepostet habe.

          Viele Grüße aus Braunschweig

          Ist es auch an der Leine? ;)

          Viele Grüße aus Frankfurt/Main,
          Patrick

          --

          _ - jenseits vom delirium - _
          <hatehtehpehdoppelpunktslashslashwehwehwehpunktatomicminuseggspunktcomslash>