I have a map of messages say:
var Mapping = {
"notnow": 2,
"expensive": 3,
"not_worth_it": 4
}
i have a bunch of html elements (lets say divs with the same name) so
<div id="notnow"></div>
,etc
now i want to attach a click handler to each of them, i run a loop as shown below
function setThemUp(){
for(var item in Mapping)
{
$("#" + item).bind('click', function () {
Apply(Mapping[item]); });
}
}
But for some reason all of them seem to get bound to "not_worth_it":4. Not to their respective values.
I'm using Jquery 1.5.
Can someone please explain why this might be happening?
My guess is that instead of the Mapping[item] being resolved to their values, it's being passed as a reference or something, that's why since the value of item eventually points to "not worth it" all of them call the function with that value itself. Any way in which i could overcome them.
Hard coding each of them as
$("#notnow").bind('click', function () {
Apply(Mapping["notnow"]); });
$("#expensive").bind('click', function () {
Apply(Mapping["expensive"]); });
$("#not_worth_it").bind('click', function () {
Apply(Mapping["not_worth_it"]); });
does work, but i would prefer an elegant solution with a loop.
Answer
i went with the closure solution
function setThemUp(){
for(var item in Mapping)
{
$("#" + item).bind('click', (function () {
return function(temp) {
Apply(Mapping[temp]); };
})(item));
}
}
Reasons being , this was more of a why the loop didn't work rather than about optimization of the jquery , since this was afterall a representative example, not my actual code, and this was an elegant solution to that problem.
Mapping[this.id]in each of your click handlers. Also, it'd probably be better to give them all a class name so you can simplify the binding even further.