Reputation: 35679
I have a question similar to the one here: Event handlers inside a Javascript loop - need a closure? but I'm using jQuery and the solution given seems to fire the event when it's bound rather than on click.
Here's my code:
for(var i in DisplayGlobals.Indicators)
{
var div = d.createElement("div");
div.style.width = "100%";
td.appendChild(div);
for(var j = 0;j<3;j++)
{
var test = j;
if(DisplayGlobals.Indicators[i][j].length > 0)
{
var img = d.createElement("img");
jQuery(img).attr({
src : DisplayGlobals.Indicators[i][j],
alt : i,
className: "IndicatorImage"
}).click(
function(indGroup,indValue){
jQuery(".IndicatorImage").removeClass("active");
_this.Indicator.TrueImage = DisplayGlobals.Indicators[indGroup][indValue];
_this.Indicator.FalseImage = DisplayGlobals.IndicatorsSpecial["BlankSmall"];
jQuery(this).addClass("active");
}(i,j)
);
div.appendChild(img);
}
}
}
I've tried a couple of different ways without success...
The original problem was that _this.Indicator.TrueImage was always the last value because I was using the loop counters rather than parameters to choose the right image.
Upvotes: 9
Views: 7311
Reputation: 117
Nikita's answer works fine as long as you are using jQuery 1.4.3 and later. For versions previous to this (back to 1.0) you will have to use bind as follows:
.bind('click', {indGroup: i, indValue : j}, function(event) {
alert(event.data.indGroup);
alert(event.data.indValue);
...
});
Hope this helps anyone else still using 1.4.2 (like me)
Upvotes: 6
Reputation: 68006
Solution by Greg is still valid, but you can do it without creating additional closure now, by utilizing eventData
parameter of jQuery click method (or bind or any other event-binding method, for that matter).
.click({indGroup: i, indValue : j}, function(event) {
alert(event.data.indGroup);
alert(event.data.indValue);
...
});
Looks much simpler and probably more efficient (one less closure per iteration).
Documentation for bind method has description and some examples on event data.
Upvotes: 13
Reputation: 321698
You're missing a function. The .click function needs a function as a parameter so you need to do this:
.click(
function(indGroup,indValue)
{
return function()
{
jQuery(".IndicatorImage").removeClass("active");
_this.Indicator.TrueImage = DisplayGlobals.Indicators[indGroup][indValue];
_this.Indicator.FalseImage = DisplayGlobals.IndicatorsSpecial["BlankSmall"];
jQuery(this).addClass("active");
}
}(i,j);
);
Upvotes: 14