JS-Variable in onclick-Ereignis einfügen?
Manuel_guest
- javascript
0 Joachim0 ChrisB0 Manuel_guest0 closure
Hallo :)
Ich wüsste gerne, wie ich folgendes Szenario in JS richtig löse:
function foobar()
{
for(var i=1; i <= 5; i++)
{
var x = document.createElement("input");
x.type="button";
x.value = i;
x.onclick = function(){alert(i);} // should alert 1 .. 5 !
document.body.appendChild(x);
}
}
Die generierten Button's sollen den Wert von 'i' ausgeben, den i zum Zeitpunkt der Zuweisung des onClick-Events hat.
Alternativ könnte ich es hier lösen, indem ich
x.onclick = function(){alert(this.value);}
machen würde, dies ist aber natürlich nicht immer möglich :)
Wo mache ich etwas falschund wie macht man es richtig?
Danke :)
Hi,
function foobar()
{
for(var i=1; i <= 5; i++)
{
var x = document.createElement("input");
x.type="button";
x.value = i;
x.onclick = function(){alert(i);} // should alert 1 .. 5 !
document.body.appendChild(x);
}
}
x.i = i;
x.onclick = function(){alert(this.i);}
Gruesse, Joachim
Hi,
x.i = i;
x.onclick = function(){alert(this.i);}
Das ist eine Möglichkeit, Closures wären eine weitere.
MfG ChrisB
Hallo,
Hi,
x.i = i;
x.onclick = function(){alert(this.i);}
so habe ich das letztendlich auch gelöst, schien mir aber nur ein workaround zu sein :)
Vielleicht der Vollständigheit wegen noch eine mir bekannte Möglichkeit:
x.onclick = new Function( "alert("+i+")" );
Allerdings versuche ich jenes immer zu vermeiden, aus Angst vor:
i = '1);window.setInterval("alert(1)",10';
Das ist eine Möglichkeit, Closures wären eine weitere.
Hm, ich würde jetzt eher sagen, dass Closures mein Problem erst verursacht haben und sehe nicht, wie ich es darüber lösen könnte? Hättest Du lust die Idee auszuführen? :)
Danke und Gruß,
Manuel
ich würde jetzt eher sagen, dass Closures mein Problem erst verursacht haben und sehe nicht, wie ich es darüber lösen könnte? Hättest Du lust die Idee auszuführen? :)
indem du bei jedem schleifendurchlauf eine anonyme funktion erzeugst (per funktionsausdruck), diese direkt ausführst und dabei den schleifenzähler als parameter übergibst
darin eine weitere closure notierst (die event-handler-funkton), die den schleifenzähler einschließt
for (var i = 0; i < 5; i++) {
(function (i) {
...
element.onclick = function () {
alert("Das korrekte i:" + i);
};
})(i);
}
die closure sorgt dafür, dass das variablenobjekt der jeweiligen äußeren (anonymen, nicht gespeicherten, nur einmal ausgeführten) funktion erhalten bleibt. das liegt in der scope chain über dem variablenobjekt der event-handler-funktion, dort wird dann die variable i gefunden
das ist aber ziemlich gefrickelt und nicht so performant (viele erzeugte funktionen und funktionsaufrufe, massig variablenobjekte, die im speicher verbleiben), es gibt einfachere und robustere methoden
weiteres findet sich im archiv zu den stichwörtern closures und schleifen