Philemon08: Variable als unveränderbaren Wert einfügen

Ich habe folgendes Problem:
Ich möchte eine Reihe von Buttons dynamisch erstellen. Das mache ich mit einer Schleife. Nun möchte ich jedem Button dieselbe Onlick Aktion hinzufügen, allerdings mit verschiedenen Parametern. Ich habe versucht das Problem so zu lösen:

  
for (i = 1; i <= 8; i++) {  
	btn = document.createElement("button")  
	btn.id = "Info"+i  
	btn.innerHTML = "Infos"  
	btn.onclick = function(){Info(i)};  
	td = document.getElementById(i+"knopf")  
	td.appendChild(btn)  
}

Wenn ich jetzt auf einen Knopf drücke, bekomme ich als Parameter immer "9".

  1. Hallo Philemon08,

    for (i = 1; i <= 8; i++) {
    btn = document.createElement("button")
    btn.id = "Info"+i
    btn.innerHTML = "Infos"
    btn.onclick = function(){Info(i)};
    td = document.getElementById(i+"knopf")
    td.appendChild(btn)
    }

      
    so greifst du auf den letzten Wert von i zu, also 9. Abhilfe wären Closures oder in diesem Fall  
    ~~~javascript
      
    	btn.nr = i  
    	btn.onclick = function(){Info(this.nr)};  
    
    

    Gruß, Jürgen

    1. Abhilfe wären Closures

      Ist nicht genau dieser Fall ein Closure?

      1. Hallo Encoder,

        Abhilfe wären Closures
        Ist nicht genau dieser Fall ein Closure?

        mein Vorschlag? Nein. Da wird nur eine Variable an den Elementknoten angehängt. Bei einer Closure müsste die Variable in einer Funktion konserviert werden.

        Gruß, Jürgen

        1. Hallo,

          Bei einer Closure müsste die Variable in einer Funktion konserviert werden.

          Das werden Variablen immer automatisch, sobald man Funktionen verschachtelst und die innere Funktion die Laufzeit der äußeren »überlebt«, also noch Referenzen auf sie existieren und sie nicht vom Garbage Collector entfernt wird.

          Der Event-Handler konserviert in diesem Falle die Variablen der äußeren Funktion, auch wenn der Event-Handler nicht auf sie zugreift. JavaScript-Engines sind hier nicht so schlau, wie man denken mag.

          Mathias

      2. Hallo,

        Abhilfe wären Closures

        Eine Closure ist Auslöser des Problems. Aber sie kann auch die Lösung sein.

        Ist nicht genau dieser Fall ein Closure?

        Ja. Sowohl Philemons08s als auch JürgenBs Code erzeugen Closures, die die Variablen der übergeordneten Funktionen einschließen. In JürgenBs Fall wird aber nicht auf den Umgebungskontext zugegriffen.

        Abhilfe wären Closures insofern, dass man pro Schleife einen neuen Funktionskontext erzeugen kann:

        var createButton = function(i) {  
          var btn = document.createElement("button");  
          btn.id = "Info" + i;  
          btn.innerHTML = "Infos";  
          // Dies ist eine Closure, die die Variablen von »createButton«  
          // einschließt, also das i mit dem gewünschten Wert:  
          btn.onclick = function(){  
            Info(i);  
          };  
          var td = document.getElementById(i+"knopf")  
          td.appendChild(btn);  
        };  
          
        for (var i = 1; i <= 8; i++) {  
          createButton(i);  
        }
        

        Mathias

    2. Vielen Dank für eure Hilfe JürgenBs Vorschlag funktioniert!