2013-12-14 6 views
8

Ich habe diesen Code:addEventListener, für(), Index. Wie benutzt man den Verschluss?

var items = this.llistat.getElementsByTagName('a'); 

for(var i = 0; i < items.length; i++){  
    items[i].addEventListener('click', function(event) { 
    alert(i); 
    }, items[i]); 
} 

, wo das Ereignis gehört wird, aber es gibt 3 Elemente und die Warnung Allways 3 auf eines der Elemente gedruckt werden (es den Index nicht respektiert),

Dos't items[i] sollte den Job als Schließung nicht tun?

danke!

+0

Das dritte Argument auf [ 'addEventListener' ] (https://developer.mozilla.org/en-US/docs/Web/API/EventTarget.addEventListener) ist ein boolescher Wert, der angibt, ob der Ereignis-Listener die Erfassungspriorität erhält (z. B. um ihn abzubrechen). Es gibt keinen "this" -Wert an. – apsillers

+0

Auch verwandt, [Javascript berüchtigte Loop-Problem?] (Http://stackoverflow.com/questions/1451009/javascript-infamous-loop-problem). –

Antwort

9

Das ist ein klassischer Verschluss Problem ist: Sie haben eine neue Funktion erstellen müssen, nicht auf das ‚i‘ Variable, sondern auf ihren Wert zum Zeitpunkt der Bindung gebunden:

var items = this.llistat.getElementsByTagName('a'); 

for(var i = 0; i < items.length; i++) { 
     items[i].addEventListener('click', listener.bind(null, i)); 
} 

function listener(index) { 
     alert(index); 
} 
+0

Danke für Ihre Anser, das funktioniert. Ist es möglich nur anonyme Funktionen zu verwenden? nur neugierig .. danke! –

+0

Gern geschehen. Die Funktion, die im Listener gespeichert ist, ist anonym. Sie möchten vielleicht nicht diese Zwischenvariable erstellen und nur den Wert von 'Listener' in addEventListener ersetzen. Aber ich denke, dass es so leichter zu verstehen ist. – GameAlchemist

+0

Javascript-Interpreter optimieren nicht, daher ist es effizienter, 'function listener (index) {return function() {...}; } 'Außerhalb der Schleife haben Sie dann die einzelne Anweisung' items [i] .addEventListener ('click', listener (i)); 'innerhalb der Schleife. Die Effizienz ergibt sich aus der einmaligen Definition der äußeren Funktion. Wie oben beschrieben, wird die äußere Funktion bei jeder Iteration der Schleife definiert (und ausgeführt). –

7

Nein, das dritte Argument von addEventListener ist das useCapture eins. Weitere Informationen finden Sie unter MDN.

Aber Sie können verwenden:

for(var i = 0; i < items.length; i++){ 
    (function(i){ 
     items[i].addEventListener('click', function(event) { 
      alert(i); 
     }, false); 
    })(i); 
} 

oder

var handler = function(event) { 
    var i = items.indexOf(this); 
    alert(i); 
}; 
for(var i = 0; i < items.length; i++){ 
    items[i].addEventListener('click', handler, false); 
} 

Die erste erzeugt einen neuen Event-Handler für jedes Element, so braucht es mehr Speicher. Der zweite verwendet den gleichen Ereignis-Listener, verwendet aber indexOf, also ist es langsamer.