Warum kann ich nicht um ein Ereignis zu jedem Element in einer Sammlung, die eher als das letzte Element in der „for () {}“ auf sich selbst verweist Aussage

StackOverflow https://stackoverflow.com/questions/2596284

Frage

Auf Window der Last sollte jedes DD Element innerhalb Quote_App ein onCLick Ereignis haben angehängt, dass Trigger die Funktion Lorem jedoch Lorem die nodeName und Id des letzten Elements kehrt in der For Aussage eher als die des Elements, das die Funktion trigged . Ich würde Lorem will den nodeName und Id des Elements zurück, das die Funktion ausgelöst.

function Lorem(Control){

/*     this.Control=Control; */
    this.Amet=function(){
        return Control.nodeName+"\n"+Control.id;
    };

};

function Event(Mode,Function,Event,Element,Capture_or_Bubble){
    if(Mode.toLowerCase()!="remove"){
        if(Element.addEventListener){
            if(!Capture_or_Bubble){
                Capture_or_Bubble=false;
            }else{
                if(Capture_or_Bubble.toLowerCase()!="true"){
                    Capture_or_Bubble=false;
                }else{
                    Capture_or_Bubble=true;
                };
            };
            Element.addEventListener(Event,Function,Capture_or_Bubble);
        }else{
            Element.attachEvent("on"+Event,Function);
        };
    };
};

function Controls(){
    var Controls=document.getElementById("Quote_App").getElementsByTagName("dd");
    for(var i=0;i<Controls.length;i++){

        var Control=Controls[i];

        Event("add",function(){

            var lorem=new Lorem(Control);
            lorem.Control=Control;
            alert(lorem.Amet());

        },"click",Controls[i]);

    };
};

Event("add",Controls,"load",window);

Zur Zeit klicken Sie auf jedem DD Element Lorem gibt immer den nodeName und Id des letzten DD Element.

Lorem sollte die nodeName und Id des Control zurückkehren (Control[i]), dass getriggerte Lorem.

Wie gehe ich darum, das passieren?

Danke!

War es hilfreich?

Lösung

Sie müssen einen Verschluss in der Schleife, wo Sie die Event-Handler sind Anbringen der Wert von i in jeder Schleife Iteration zu erfassen.

  for(var i=0;i<Controls.length;i++) {   
    (function() {
        var Control=Controls[i];

        Event("add",function(){

            var lorem=new Lorem(Control);
            lorem.Control=Control;
            alert(lorem.Amet());

         },"click",Controls[i]);
    })();
  };

Hier habe ich einen Verschluss oben mit Hilfe von JavaScript guten Freund, der selbst Aufruf anonyme Funktion erstellt.

Der Grund, eine Schließung erforderlich ist, ist, dass ohne sie der Wert von i an dem Punkt, an dem jeder Event-Handler-Funktion ausgeführt wird, wäre der Wert von i in der letzten Schleife Iteration, nicht das, was wir wollen. Wir wollen den Wert von i wie es in jeder Schleife Iteration ist, an dem Punkt, an dem wir jeden Event-Handler-Funktion deklarieren, so müssen wir diesen Wert in jeder Iteration erfassen. eine anonyme Funktion, die ausgeführt wird, sobald es deklariert ist, ist ein guter Mechanismus für den gewünschten Wert zu erfassen.

Ein weiterer Punkt, etwas off topic, aber es kann Ihnen helfen, ist, dass Ereigniserfassung nicht in jedem Browser unterstützt wird ( ahem , IE), aber Ereignis sprudelnden ist. Damit wird an dem useCapture boolean Flag in addEventListener ziemlich nutzlos für die Entwicklung von Cross-Browser-Web-Anwendungen. Ich würde daher nicht raten, es zu benutzen.

Eine weitere Sache, JavaScript verwendet in der Regel Kamel Gehäuse für Funktionsnamen und Variablennamen. Pascal Gehäuse ist nur für den Konstruktor-Funktionen (Funktionen, die Objekte zu erstellen) verwendet.

Andere Tipps

Wenn Sie eine Funktion erstellen, die außerhalb davon auf Variablen bezieht, werden diese Verweise auf die Zeit, die Sie diese Funktion aufrufen aufgelöst werden.

In Ihrem Fall:

var functions = [];
function outer() {
    for (var i = 0; i < N; i++) { // <------------
        functions[i] = function() { //            |
            alert(i); // <-- this 'i' refers to this one
        }
    } // At the end of the for loop, i == N (or N+1?)
}
functions[x](); // Will show N (or N+1)
// because that's the current value of i in the outer function
// (which is kept alive just because something refers to it)

Was wollen Sie tun, ist Capture der Wert von ‚i‘ bei jedem Schritt der Schleife für eine spätere Auswertung, z.

var functions = [];
function outer() {
    for (var i = 0; i < N; i++) { // <---------------------------------------
        functions[i] = (function(my_i) { // <----                            |
            return function () { //              |                           |
                alert(my_i); // my_i refers to this which is a copy of 'i' there
            }
        }(i)); // run function(with my_i = the i at each step of the loop)
    }
}
functions[x](); // Will show x

Sie können sehen, gibt es eine innere Funktion, die als Parameter eine Kopie des aktuellen Zähler bekommt. Diese innere Funktion bleibt am Leben mit dieser Kopie, so dass später Anrufe auf den gespeicherte innest Funktion gibt den Wert des my_i der Funktion, die sie geschaffen - Clear? : -)

Dies ist die wunderbare Welt der Verschlüsse. Es kann ein bisschen irreen nehmen sie zuerst zu bekommen, aber dann werden Sie froh sein, Sie haben, so gehen und „javascript Schließungen“ zum Tode google!

Dies kann eine offensichtliche Variante der Antwort des Russ Cam sein:

function Controls() {
  var Controls = document.getElementById("Quote_App").getElementsByTagName("dd");

  var createHandlerFor = function(CurrentControl) {
    return function() {
      var lorem=new Lorem(CurrentControl);
      lorem.Control=CurrentControl;
      alert(lorem.Amet());
    }
  };

  for (var i=0; i<Controls.length; i++) {
    Event("add", createHandlerFor(Controls[i]), "click", Controls[i]);
  }
};
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top