George Ristic
George Ristic

Reputation: 77

Adding event listener to multiple elements using for loop and passing different parameters

<div id="mydiv0"></div>
<div id="mydiv1"></div>
<div id="mydiv2"></div>


var myArray = [
  document.getElementById("mydiv0"),
  document.getElementById("mydiv1"),
  document.getElementById("mydiv2")
];

function myFunction(x){
  alert("my number is " + x);
}

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

I want to attach event listener to each element in myArray. When clicked, an alert message should be displayed showing numbers 0,1 and 2 for mydiv0, mydiv1 and mydiv2 respectively. I tried using for loop as seen in the example above, but no matter which div I click on, I get "my number is 3" message. Is there a way to pass the different values of variable i as a parameter of myFunction?

Upvotes: 1

Views: 599

Answers (5)

Devesh
Devesh

Reputation: 170

Just use 'let' instead of 'var' as below :

for(let i = 0; i < myArray.length; i++){
    myArray[i].addEventListener("click", function(){myFunction(i);});
}

'let' allows you to declare variables that are limited in scope to the block, statement, or expression on which it is used. This is unlike the 'var' keyword, which defines a variable globally, or locally to an entire function regardless of block scope.

Upvotes: 1

Chun Lin
Chun Lin

Reputation: 544

Alternatively, you can use data attribute as follows.

<div id="mydiv0" data-value="1"></div>
<div id="mydiv1" data-value="2"></div>
<div id="mydiv2" data-value="3"></div>

for(var i = 0; i < myArray.length; i++){
    myArray[i].addEventListener("click",  function() {
        myFunction(this.getAttribute('data-value'));
    });
}

Upvotes: 1

Giulio Bambini
Giulio Bambini

Reputation: 4755

You can simply declare the variable in the loop with let instead of var that creates a block scope local variable.

var myArray = [
  document.getElementById("mydiv0"),
  document.getElementById("mydiv1"),
  document.getElementById("mydiv2")
];

function myFunction(x){
  alert("my number is " + x);
}

for(let i = 0; i < myArray.length; i++){
  myArray[i].addEventListener("click", function(){myFunction(i);});
}
<div id="mydiv0">Div 0</div>
<div id="mydiv1">Div 1</div>
<div id="mydiv2">Div 2</div>

Upvotes: 3

ic3b3rg
ic3b3rg

Reputation: 14927

Use bind:

var myArray = [
  document.getElementById("mydiv0"),
  document.getElementById("mydiv1"),
  document.getElementById("mydiv2")
];

function myFunction(x){
  alert("my number is " + x);
}

for(var i = 0; i < myArray.length; i++){
  myArray[i].addEventListener("click", myFunction.bind(null, i));
}
div {
  height: 20px;
  width: 200px;
  border: 1px solid black;
}
<div id="mydiv0"></div>
<div id="mydiv1"></div>
<div id="mydiv2"></div>

Upvotes: 1

Praveen Gupta
Praveen Gupta

Reputation: 246

You have to create a isolated scope for click callback.

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

Upvotes: 1

Related Questions