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?

0

2 Answers 2

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.

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

1 Comment

is it called infamous loop problem???
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) { ... });

1 Comment

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!

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.