How to add event listeners to an array of objects

Ryan Williams picture Ryan Williams · Jul 31, 2013 · Viewed 53.3k times · Source

I have an array of objects (specifically easelJS images) - something like this:

var imageArray = new Array;
gShape  = new createjs.Shape();
// shape is something
imageArray.push(gShape);

What I want to do is have an event listener instead of:

gShape.addEventListener("click", function() {alert"stuff"});

I want the program to know specifically which region is clicked so that I can send an alert box in the following way:

imageArray[index].addEventListener("click", function(){
    alert " you clicked region number " + index}

Answer

Sushanth -- picture Sushanth -- · Jul 31, 2013

Sure. You can just use a closure to save the index of that iteration. Otherwise there are shared by the same function scope and will give you the value of the same iteration. Creating a separate function for each will save the state of that inside the function.

var imageArray = new Array;
gShape = new createjs.Shape();
 // shape is something
 imageArray.push(gShape); // Dumped all the objects

for (var i = 0; i < imageArray.length; i++) {
   (function(index) {
        imageArray[index].addEventListener("click", function() {
           console.log("you clicked region number " + index);
         })
   })(i);
}

or better

 for(var i = 0; i < imageArray.length; i++) {
       imageArray[i].addEventListener("click", bindClick(i));
 }

 function bindClick(i) {
    return function() {
        console.log("you clicked region number " + i);
    };
 }

ES6 to the rescue

let imageArray = [];
gShape = new createjs.Shape();
// shape is something
imageArray.push(gShape); // Dumped all the objects

for (let i = 0; i < imageArray.length; i++) {
  imageArray[i].addEventListener("click", function() {
    console.log("you clicked region number " + i);
  });
}

Using the let keyword creates a block scoping for the variable in iteration and will have the correct index when the event handler is invoked.