Reputation: 1655
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
Reputation: 146269
$(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
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
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
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
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