views:

1009

answers:

3

I'm trying to figure out how to store external variable values in the functions created during jQuery's click() event. Here's a sample of the code I'm working with now.

for(var i=0; i<3; i++){
 $('#tmpid'+i).click(function(){
  var gid = i;
  alert(gid);
 });
}

<div id="tmpid0">1al</div>
<div id="tmpid1">asd</div>
<div id="tmpid2">qwe</div>

So what's happening is that the events are attaching properly, but the value of 'gid' is always the last incremented value of 'i'. I'm not sure how to setup the private variable in this situation.

+5  A: 

You can create a closure and assign i to a local variable of the closure. The gid variable will then be assigned the value of i at the point that the closure was created rather than when the function is run.

for(var i=0; i<3; i++){
    (function() {
        var gid = i;
        $('#tmpid'+i).click(function(){
            alert(gid);
        });
    })();
}
Rich Seller
This did work for me. Its an interesting use of an anonymous function.
Geuis
Is it? I'm fairly new to Javascript, but my Greasemonkey scripts have quite a few JQuery loops and this seemed a natural way to handle the functions
Rich Seller
A: 

You've created a closure, where the variable "i" is shared between multiple click handlers.

Since Javascript doesn't have block scope, you'll need to pass "i" to a new function so it is copied-by-value to a new instance:

function bindStuff(i) {
    $('#tmpid'+i).click(function(e){
                    var gid = i;
                    alert(gid);
            });
}

for(var i=0; i<3; i++){ bindStuff(i); }

Here's another similar question: http://stackoverflow.com/questions/750486/javascript-closure-inside-loops-simple-practical-example

Jeff Meatball Yang
For some reason I can't get this work for me. I still get the original problem.
Geuis
OMG, I really misunderstood Javascript scope. It does not have block scoping. I've edited my answer, but you can definitely use the data() method - it's a nicer way to pass data around.
Jeff Meatball Yang
A: 

I read back up on jQuery's native data() method. I implemented this and it works as well. Its hiding some of the actual functionality of how the closures are being handled, but its simple and pretty clean to implement.

Geuis