0

Possible Duplicate:
adding ‘click’ event listeners in loop

I make a demo.So let's see the HTML first.

<a href="#" id="testA">testA</a>
<a href="#" id="testB">testB</a>    

<div id="showA">showA</div>
<div id="showB">showB</div>

And i want to bind click events to Elements a . and when it clicks, alert the related div. (click id="testA",alert id="showA" ...)

And i write the jQuery code.

var arr = ["A","B"];    
  for(var i=0;i<arr.length;i++){
    $("#test"+arr[i]).click(function(){
      alert($("#show"+arr[i]).text())
    });
  }

But it doesn't work. I debug this code and find that this code alert($("#show"+arr[i]).text())

only run when I click the a element . and when I click a . the variable i is 3 already.

So what should I do?

Community
  • 1
  • 1
SeasonHuang
  • 157
  • 1
  • 1
  • 9

2 Answers2

5

The problem is that once the event handler is executed, i will have reached its final value and be stuck at arr.length. You can use a closure to capture the value of i at each iteration of the loop:

var arr = ["A","B"];    
for(var i=0;i<arr.length;i++) {
    (function (i) {
        $("#test"+arr[i]).click(function(){
            alert($("#show"+arr[i]).text())
        });
    }(i));
}

Here's a working example.

James Allardice
  • 164,175
  • 21
  • 332
  • 312
2

The easiest/cleanest solution would be to use a forEach loop instead.

arr.forEach(function(val) {
  $("#test"+ val).click(function() {
    alert($("#show"+ val).text())
  });
});

If you want support for older browsers there are many polyfills online.

Edit: Since your using jQuery you can also do it with $.each:

$.each(arr, function(idx, val) { ... });
elclanrs
  • 92,861
  • 21
  • 134
  • 171
  • You can even add `HTMLCollection.prototype.forEach = Array.prototype.forEach; NodeList.prototype.forEach = Array.prototype.forEach;` so you can forEach HTMLCollections and NodeList. Nice Solution! – Peheje Apr 26 '18 at 08:57