views:

27

answers:

1

Hi,

I'm having a bit of a difficulty using jQuery to bind a function to an element. Basically I have a set of divs that I load using JSON. Each of the JSON items have an associated "action" that defines what function to call if that div is clicked.

As I iterate through each of the JSON items, I do (editied for clarity):

for (var i = 0; i < JSONOBJECT.length; i++) {
   var divbox = $('<div id="' + i + '"><img /></div>');

   var action = JSONOBJECT[i]["action"];
   $(divbox).click(function () {
      eval(action); // bind function
   });

   $('.navigationarea').append(divbox); // Append to area
}

So for example, JSONOBJECT[0]["action"] can contain a "doThis()", while JSONOBJECT[1]["action"] can contain a "doThis2()".

The problem is that action always ends up being the action associated with the last item in the JSON object. I know this is an issue related to localizing the variable (or making a copy?) but I'm missing it.

Can I get some help? Thanks in advance.

+1  A: 

Your problem is that the action variable is shared by all of the anonymous methods.

In your specific case, the best solution is to write divbox.click(new Function(action)).
This will also be faster because the code will only be parsed once, not once per click.

In general, the solution is to put the code containing the anonymous function into a separate function, and pass the variable to the separate function as a parameter.

EDIT: Your code can be rewritten like this:

for (var i = 0; i < JSONOBJECT.length; i++) {
    $('<div id="' + i + '"><img /></div>')
        .click(new Function(JSONOBJECT[i].action))
        .appendTo($('.navigationarea'));
}
SLaks
Thank you. That's a great piece of implementation advice to, and I also refactored the code nicely.
Rio