AddEventListener, for (), index. how to use closure?

I have this code:

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

where the event is listened, but there are 3 elements, and the notification always prints 3 on any of the elements (this does not correspond to the index),

Dosen't items[i] shouldn't do the job like a closure?

thanks!

+8
javascript closures for-loop addeventlistener
source share
2 answers

This is a classic closing problem: you should create a new functional binding, not the "i" variable, but its value during the binding:

 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); } 
+9
source share

No, the third argument to addEventListener is useCapture . See MDN for more details.

But you can use:

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

or

 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); } 

The first creates a new event handler for each element, so it needs more memory. The second repeats the same event listener, but uses indexOf , so it is slower.

+7
source share

All Articles