Sonntag, Mai 31, 2020

Javascript mehrere dynamische addEventListener erstellt in for-Schleife – die übergabe von Parametern funktioniert nicht

Ich wollen, verwenden Sie die Ereignis-Listener, um zu verhindern, dass Ereignis-bubbling auf ein div in einem div-Tag mit onclick-Funktionen. Dies funktioniert, ist die übergabe von Parametern, wie ich wollte:

<div onclick="doMouseClick(0, 'Dog', 'Cat');" id="button_id_0"></div>
<div onclick="doMouseClick(1, 'Dog', 'Cat');" id="button_id_1"></div>
<div onclick="doMouseClick(2, 'Dog', 'Cat');" id="button_id_2"></div>

<script>
function doMouseClick(peram1, peram2, peram3){
    alert("doMouseClick() called AND peram1 = "+peram1+" AND peram2 = "+peram2+" AND peram3 = "+peram3);
}
</script>

Jedoch habe ich versucht, zu erstellen Sie mehrere event-Listener in einer Schleife mit diesem:

<div id="button_id_0"></div>
<div id="button_id_1"></div>
<div id="button_id_2"></div>

<script>
function doMouseClick(peram1, peram2, peram3){
    alert("doMouseClick() called AND peram1 = "+peram1+" AND peram2 = "+peram2+" AND peram3 = "+peram3);
}

var names = ['button_id_0', 'button_id_1', 'button_id_2'];

    for (var i=0; i<names.length; i++){

        document.getElementById(names[i]).addEventListener("click", function(){
        doMouseClick(i, "Dog", "Cat");

    },false);

}

</script>

Richtig weist die Klick-Funktion, um jedes div, aber der erste parameter für jeden, der peram1 ist 3. Ich hatte erwartet, 3 verschiedene event-Handler alle vorbeifahrenden verschiedene Werte von i für peram1.

Warum ist das passiert? Sind die event-Handler nicht alle trennen?

InformationsquelleAutor KDawg | 2013-01-05

4 Kommentare

  1. 19

    Problem ist, Verschlüsse, da JS nicht haben block scope (nur Funktion, Umfang) i ist nicht, was Sie denken, weil die event-Funktion erstellt mit einem anderen Bereich, so dass durch die Zeit, die Sie verwenden i es ist bereits der aktuellste Wert aus der for Schleife. Sie benötigen, um den Wert von i.

    Mithilfe einer IIFE:

    for (var i=0; i<names.length; i++) {
      (function(i) {
        //use i here
      }(i));
    }

    Mit forEach:

    names.forEach(function( v,i ) {
      //i can be used anywhere in this scope
    });
    Ich danke Ihnen sehr : ) !
    Danke. Ich Frage mich, warum i fiel aus dem Rahmen und zurückgeben undefined element.

    InformationsquelleAutor elclanrs

  2. 3

    Wie bereits schon das problem mit den Verschlüssen und Geltungsbereich von Variablen. Ein Weg, um sicherzustellen, dass der richtige Wert übergeben bekommt, ist zu schreiben eine andere Funktion zurückgibt, die die gewünschte Funktion, halten Sie die Variablen in den richtigen Rahmen. jsfiddle

    var names = ['button_id_0', 'button_id_1', 'button_id_2'];
    
    function getClickFunction(a, b, c) {
      return function () {
        doMouseClick(a, b, c)
      }
    }
    for (var i = 0; i < names.length; i++) {
      document.getElementById(names[i]).addEventListener("click", getClickFunction(i, "Dog", "Cat"), false);
    }

    Und zu veranschaulichen eine Möglichkeit, Sie tun können, diese mit einem Objekt statt:

    var names = ['button_id_0', 'button_id_1', 'button_id_2'];
    
    function Button(id, number) {
      var self = this;
      this.number = number;
      this.element = document.getElementById(id);
      this.click = function() {
        alert('My number is ' + self.number);
      }
      this.element.addEventListener('click', this.click, false);
    }
    for (var i = 0; i < names.length; i++) {
      new Button(names[i], i);
    }

    oder etwas anders:

    function Button(id, number) {
      var element = document.getElementById(id);
      function click() {
        alert('My number is ' + number);
      }
      element.addEventListener('click', click, false);
    }
    for (var i = 0; i < names.length; i++) {
      new Button(names[i], i);
    }
    Dies war sehr hilfreich, vielen Dank. Ein wenig Fortgeschritten für mich, als ich gerade angefangen mit Ereignis-Listener in javascript – ich will studieren diese weiter.

    InformationsquelleAutor Stuart

  3. 1

    Alles ist global in javascript. Es ist die variable aufrufen i die 3 nach der Schleife…wenn Sie i um 1000 nach der Schleife, dann würden Sie sehen, jeden Methodenaufruf erzeugen 1000 für i.

    Wenn Sie wollen, um den Status beizubehalten, dann sollten Sie Objekte verwenden. Haben das Objekt eine callback-Methode, die Sie zuweisen, um die click-Methode.

    Erwähnt Sie tun dies für Ereignis-bubbling…für das beenden-Ereignis bublling, die Sie wirklich nicht brauchen, dass, wie es gebaut ist, in der Sprache. Wenn Sie wollen, um zu verhindern, dass Ereignis-bubbling, dann sollten Sie das stopPropagation() Methode der event Objekt an den Rückruf übergeben wird.

    function doStuff(event) {
        //Do things
        //stop bubbling
        event.stopPropagation();
    }
    Vielen Dank für die Hilfe bei der stopPropogation () – Es löste das andere Teil von meinem problem. Der eventlistener ist Links mich mit der gleichen sprudelnden problem, wie Sie vorgeschlagen -, dass ich versucht hatte, Sie zu lösen – aber diese Antwort hier löste mein brodelndes problem. Nochmals vielen Dank : ) Mann! diese Stackoverflow ist eine hilfreiche Gruppe von Leuten!
    Eure Kommentare zu „wenn du ich 1000 nach der Schleife, dann würden Sie sehen, jeden Methodenaufruf erzeugen 1000 zum ich“ wurden auch völlig korrekt : )

    InformationsquelleAutor jyore

  4. 1

    Ist es wegen der Sperrungen.

    Check this out: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures#Creating_closures_in_loops_A_common_mistake

    Den sample-code und der code ist im wesentlichen der gleiche, es ist ein häufiger Fehler für diejenigen, die nicht wissen, „closure“.

    Um es einfach auszudrücken, wenn Sie Ihre erstellen Sie eine handler-Funktion, die es nicht eben greift auf die variable i von der äußeren Umwelt, aber auch „erinnert“ sich i.

    So, wenn der handler aufgerufen wird, wird es die i aber die variable i ist jetzt, nach der for-Schleife, 2.

    Links zu externen Ressourcen sind erwünscht, aber bitte fügen Sie Rahmen um den link, damit Ihre Kolleginnen und Nutzer haben eine Vorstellung davon, was es ist und warum es da ist. Immer zitieren die meisten relevanten Teil eine wichtige Verbindung, im Falle der Ziel-Website nicht erreichbar ist oder dauerhaft offline ist. Aus Beantworten.
    Danke für Eure Erinnerung. Ich habe gerade bearbeitet meine post.

    InformationsquelleAutor olindk

Kostenlose Online-Tests