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
  • 146,912
  • 75
  • 297
  • 349
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,673
  • 7
  • 49
  • 94