Event-Handler in einer Javascript-Schleife – brauchen Sie eine Schließung?

Lesezeit: 2 Minuten

Event Handler in einer Javascript Schleife brauchen Sie eine Schliesung
matt b

Ich arbeite mit ein wenig HTML- und Javascript-Code, den ich von jemand anderem übernommen habe. Die Seite lädt alle zehn Sekunden eine Datentabelle neu (über eine asynchrone Anfrage) und baut die Tabelle dann mithilfe von DOM-Code neu auf. Der betreffende Code sieht in etwa so aus:

var blah = xmlres.getElementsByTagName('blah');
for(var i = 0; i < blah.length; i++) {
    var td = document.createElement('td');
    var select = document.createElement('select');
    select.setAttribute("...", "...");
    select.onchange = function() {
        onStatusChanged(select, callid, anotherid);
    };
    td.appendChild(select);
}

Wenn das onchange Ereignis wird für a ausgelöst <select> -Element scheint es jedoch so, als würden dieselben Werte an das übergeben onStatusChanged() Methode für alle <select> in der Tabelle (ich habe überprüft, dass in jeder Iteration der Schleife, callid und anotherid erhalten neue, eindeutige Werte).

Ich vermute, dass dies auf die Art und Weise zurückzuführen ist, wie ich den Ereignishandler mit dem setze select.onchange = function() Syntax. Wenn ich verstehe, wie dies richtig funktioniert, legt diese Syntax eine Schließung für das onchange-Ereignis fest, um eine Funktion zu sein, die sich auf diese beiden Referenzen bezieht, die am Ende einen endgültigen Wert haben, auf den sie bei der letzten Iteration der Schleife eingestellt sind. Wenn das Ereignis ausgelöst wird, der Wert, auf den verwiesen wird von callid und anotherid ist der bei der letzten Iteration festgelegte Wert, nicht der bei der einzelnen Iteration festgelegte Wert.

Gibt es eine Möglichkeit, den Wert der Parameter zu kopieren, an die ich übergebe? onStatusChanged()?

Ich habe den Titel geändert, um die Frage und die akzeptierte Antwort besser widerzuspiegeln.

Sie müssen hier tatsächlich eine Schließung implementieren. Dies sollte funktioniert (lass es mich wissen – ich habe es nicht getestet)

var blah = xmlres.getElementsByTagName('blah');
for(var i = 0; i < blah.length; i++) {
    var td = document.createElement('td');
    var select = document.createElement('select');
    select.setAttribute("...", "...");
    select.onchange = function(s,c,a)
    {
        return function()
        {
            onStatusChanged(s,c,a);
        }
    }(select, callid, anotherid);
    td.appendChild(select);
}

  • Eine andere Lösung, die ich entdeckt habe – wirklich eine Problemumgehung – wäre, die callid und die anotherid als Attribute im DOM-Element zu speichern und diese innerhalb des Eventhandlers einfach über this.getAttribute() zu referenzieren.

    – matt b

    4. Dezember 2008 um 19:36 Uhr

  • Workaround würde ich das nicht nennen. Was ich erwarten würde, ist, dass der Handler einmal festgelegt wird (nicht jedes Mal durch die Schleife) und die Variablen selbst entdeckt.

    – dkretz

    4. Dezember 2008 um 22:37 Uhr

  • Beachten Sie, dass das, was OP hat, auch eine Schließung ist. Und in der Tat hat OP die repräsentativere Form, in der Ihre Schließung ihre Umgebung mit anderen Schließungen teilt (pro Schleifendurchlauf wird eine Schließung erstellt). Aber genau das gibt den unerwarteten Effekt.

    – Jo So

    2. Februar 2014 um 16:49 Uhr

Ändern Sie einfach das “var” in der for-Schleife in “let” und es funktioniert wie ein Zauber.

Hinweis: JavaScript For Loop Click Event Lösung Nr. 4

914560cookie-checkEvent-Handler in einer Javascript-Schleife – brauchen Sie eine Schließung?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy