CyberSwiss: funktion in onClick dynamisch hinzufügen

Sali zäme
Ich weiss, es gibt hier zahlreiche Posts zu diesem Thema. Leider finde ich keine Lösung zu meinem Problem. Vielleicht kann mir dennoch jemand hier helfen. Es geht darum, dass ich eine Tabelle habe, die ich dynamisch aufbaue. In jeder Tabellenzeile gibt es ein Image, das das Delete-Button fungiert. Die Delete Funktion lautet:

deleteRow(tableId,newRowNo,confirmDelete);

und funktioniert auch. Das Problem ist nun, dass anscheinend beim hinzufügen einer neuen Zeile die 'newRowNo' in allen Zeilen auf die neuste RowNo aktualisiert wird, was ich nicht will. Was mache ich hier falsch, oder wo liegt mein Denkfehler?

Anbei noch den Code für den Aufbau des 'Delete-Image':

var img_5 = null;
img_5 = document.createElement('IMG');
img_5.setAttribute("id", newRowId + "_C5_DEL");
img_5.setAttribute("src", imgDelete.src);
img_5.onclick=function(){deleteRow(tableId,newRowNo,confirmDelete);}

Danke für die Hilfe

  1. Hi,

    var img_5 = null;
    img_5 = document.createElement('IMG');
    img_5.setAttribute("id", newRowId + "_C5_DEL");
    img_5.setAttribute("src", imgDelete.src);
    img_5.onclick=function(){deleteRow(tableId,newRowNo,confirmDelete);}

    wenn Du die Funktion aufrufst steckt in den parametern möglicherweise nicht mehr der Wert, den diese beim Setzen des eventhandlers besassen, z.B wenn Du durch die Rows loopst.
    Einfache lösung: Werte als image eigenschaft speichern:

    img_5.tableId =  tableId;
    img_5.onclick=function(){deleteRow(this.tableId,...,...);}

    Gruesse, Joachim

    --
    Am Ende wird alles gut.
    1. Hi,

      var img_5 = null;
      img_5 = document.createElement('IMG');
      img_5.setAttribute("id", newRowId + "_C5_DEL");
      img_5.setAttribute("src", imgDelete.src);
      img_5.onclick=function(){deleteRow(tableId,newRowNo,confirmDelete);}

      wenn Du die Funktion aufrufst steckt in den parametern möglicherweise nicht mehr der Wert, den diese beim Setzen des eventhandlers besassen, z.B wenn Du durch die Rows loopst.
      Einfache lösung: Werte als image eigenschaft speichern:

      img_5.tableId =  tableId;
      img_5.onclick=function(){deleteRow(this.tableId,...,...);}

      Gruesse, Joachim

      Sali Joachim

      Genau das ist die Lösung meines Problems. herzlichen Dank. Mir war einfach nicht klar, wieso die Funktionsparameter immer wieder überschrieben werden, resp. wie man diese im Image Element 'persistieren' kann.

      Nochmals DANKE!

      1. Hi,

        Genau das ist die Lösung meines Problems. herzlichen Dank. Mir war einfach nicht klar, wieso die Funktionsparameter immer wieder überschrieben werden,

        Alternativ kannst Du auch ein so genanntes Closure verwenden:

        <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
        "http://www.w3.org/TR/1999/REC-html401-19991224/loose.dtd">
        <html>
        <head>
        <script type="text/javascript">
            function init () {
                var func, cnt, txt, p, div;
                for (var i = 0; i < 5; i++) {
                    cnt     =  i + 1;
                    div     =  document.getElementById("main");
                    p       =  document.createElement("p");
                    txt     =  document.createTextNode("Wert: " + cnt);
                    func    =  function () {
                        var y =  cnt;
                        var x =  function () {
                            alert(y);
                        }
                        p.onclick=x;
                    }
                    func();
                    p.appendChild(txt);
                    div.appendChild(p);
                }
            }
        </script>
        </head>
        <body onload="init()">
            <div id="main"></div>
        </body>
        </html>

        Guter Artikel hierzu: http://aktuell.de.selfhtml.org/artikel/javascript/organisation/

        Gruesse, Joachim

        --
        Am Ende wird alles gut.
      2. Hallo,

        img_5.onclick=function(){deleteRow(tableId,newRowNo,confirmDelete);}

        Mir war einfach nicht klar, wieso die Funktionsparameter immer wieder überschrieben werden

        Die Frage ist vielmehr, warum diese Variablen überhaupt in der onclick-Funktion verfügbar sind! Die Antwort ist, weil du Funktionen verschachtelst und verschachtelte Funktionen Zugriff auf die lokalen Variablen der äußeren Funktion haben - und zwar auch dann noch, wenn die äußere Funktion längst abgelaufen ist. Dieses Phänomen nennt sich Closures und du hast es hier schon verwendet, ohne es zu wissen.

        Allerdings steckt die obige Anweisung wohl in einer Schleife. In der Schleife erzeugst du also viele Closure-Funktionen, die alle auf ein und dieselben Variablen "zeigen". In jeder dieser onclick-Funktionen sind die Variablen tableId, newRowNo und confirmDelete "eingeschlossen". Dabei werden keine Kopien angelegt, sondern viele Referenzen auf ein und dieselbe Speicherstelle angelegt.

        Jetzt musst du dir vor Augen führen, wie das Programm abläuft: Die Funktion mit der Schleife läuft durch und weist die onclick-Handler zu. Dann wird sie beendet, aber die besagten Variablen sind konserviert, weil viele Funktionen sie "eingeschlossen" haben. Deren Werte nach dem Durchlauf der Schleife sind nunmal die des letzten Schleifendurchlaufs. Also haben alle onclick-Handler nicht Zugriff auf die Werte, die die Variablen in dem jeweiligen Schleifendurchlauf hatten, sondern auf die letztendlichen Werte vom Ende der Funktionsausführung.

        Zwei Alternativen wurden hier schon genannt, das Speichern am Element und das bewusste Erzeugen einer Closure, die allerdings die aktuellen Variablenwerte selbst in lokalen Variablen speichert, damit diese bei dessen Ausführung verfügbar sind.

        Siehe auch:
        </archiv/2008/6/t173073/#m1135468>
        </archiv/2006/9/t136283/#m885076>
        </archiv/2006/12/t141557/#m919914>
        http://www.howtocreate.co.uk/referencedvariables.html

        Mathias