Rafael
Rafael

Reputation: 1655

JQuery .click not working as I expected

I have a question about the .click function in Jquery. I have this code:

for (var i = 0; i < 5; i++) {
    var divTest = $('<div></div>');
    divTest.text("My Div " + i);
    divTest.click(function() {
        alert("Alert: Div " + i);
    });
    $('#myTest').append(divTest);
}​

I expected to add five divs to the "myTest" element and for each div the onclick function would show an alert with the corresponding div number.

The divs were added properly, but when I click on the divs I always get the alert with the text: "Alert: Div 5". Why? What I have to change to generate the behavior that I'm expecting?

Here is my jsFiddle: http://jsfiddle.net/BKFGm/2/

Upvotes: 8

Views: 225

Answers (6)

The Alpha
The Alpha

Reputation: 146269

You can also try this

$(function() {
    for(var i = 0; i < 5; i++){
        var divTest = $('<div/>', {
            'text':"My Div " + i,
            'click':(function(i){
                return function(){
                    alert("Div: " + i);
                }
            })(i)
        });
        $('#myTest').append(divTest);
    }
});​

DEMO.

Upvotes: 0

VisioN
VisioN

Reputation: 145458

In this case you should use closure:

(function(i) {
    divTest.click(function() {
        alert("Div: " + i);
    });
})(i);

DEMO: http://jsfiddle.net/BKFGm/4/


Another option is to pass i in the eventData map:

divTest.click({ i: i }, function(e) {
    alert("Div: " + e.data.i);
});

DEMO: http://jsfiddle.net/BKFGm/11/

Upvotes: 11

Reflective
Reflective

Reputation: 3917

.click works in a different scope than your cycle and it is undefined when your click handler is executed, unless you have an other i variable on the global scope.

Upvotes: 0

BoltBait
BoltBait

Reputation: 11489

When the Alert happens, the variable i is already set to 5.

Upvotes: 0

Shmiddty
Shmiddty

Reputation: 13967

This is a scope issue. Also, it's a very commonly asked question here.

The simple fix:

for(var i = 0; i < 5; i++){
     var divTest = $('<div></div>')
         divTest .text("My Div " + i);

    (function(index){
        divTest .click(function () {
             alert("Div: " + index);
                    });
    })(i);

        $('#myTest').append(divTest);
}

Upvotes: 0

Niet the Dark Absol
Niet the Dark Absol

Reputation: 324790

Once again, a classic case of closures. i keeps getting incremented, whereas you want to anchor it in the click event. Try this:

for( i=0; i<5; i++) {
  (function(i) {
    // your code that depends on `i` here
  })(i);
}

Upvotes: 5

Related Questions