7

I'm trying to add an event listener to all elements with a class of section, however it only applies it to the last object in the node list.

var section = document.querySelectorAll('.section');
for(var i=0;i<section.length;i++){
var elem = section[i];
elem.addEventListener('click', function () {move (elem)}, false); 
}

Is there a way I can add the event listener for each one?

  • 4
    See http://stackoverflow.com/questions/750486/javascript-closure-inside-loops-simple-practical-example for the generic answer. – pimvdb Dec 07 '12 at 21:41

2 Answers2

5

The issue is that there's no block scope in JavaScript. So elem is overwritten each iteration, instead of being declared as a new variable each time. The only way to declare new variables in each iteration is through a function:

for(var i = 0; i < section.length; i++){
  (function(elem) {
    elem.addEventListener('click', function() { move(elem); }, false);
  })(elem);
}

But addEventListener sets this to the element, so in your case you can neatly do:

for(var i = 0; i < section.length; i++){
  elem.addEventListener('click', function () { move(this); }, false);
}
pimvdb
  • 151,816
  • 78
  • 307
  • 352
1

that's because you are referencing elem and i inside function. I can suggest trying

var section = document.querySelectorAll('.section');
for(var i=0;i<section.length;i++){
    var handler = (function(ind){ 
        return function () {
             move (section[ind]);
        }
    })(i) 

    elem.addEventListener('click', handler, false); 
}
Eugeny89
  • 3,797
  • 7
  • 51
  • 98