1
<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?

5 Answers 5

3

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>

Sign up to request clarification or add additional context in comments.

2 Comments

Thank you. This way seems to be much cleaner compared to wrapping or bind.
@GeorgeRistic, yes you right. bind and (function(){})() are the old ways of doing the solution as let is new feature.....
1

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

Comments

1

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>

Comments

1

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

Comments

1

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.