1

I have a list of nodes and I am going to draw each node using a raphael object. I have the following loop:

for(var i=0; i<curNodes.length; i++){
    var node = curNodes[i];
    var obj = paper.rect(node.getX(), node.getY(), node.width, node.getHeight())
   .attr({fill:nodes[i].getColor(), "fill-opacity": 0.6})
   .click(function(e){ onMouseClicked(i,e); });
}

on click, I want to call a function which can view some data associated with 'i' th element of curNodes array. However, all the time the last 'i' is passed to this function. my function is:

var onMouseClicked = function(i, event){
switch (event.which) {
    case 1:
        this.attr({title: curNodes[i].name});
        break;
    }
}

How should I access the correct index when calling a function?

hAlE
  • 1,283
  • 3
  • 13
  • 19
  • See: http://stackoverflow.com/questions/3572480/please-explain-the-use-of-javascript-closures-in-loops/3572616#3572616 – slebetman Apr 25 '13 at 04:09

2 Answers2

3

Try this:

.click((function (i) {
    return function (e) {
        onMouseClicked(i,e);
    };
})(i));

Like you noticed, the value of i (or the parameter in your function) is the last index from the for loop. This is because the click event doesn't happen immediately - the binding does, but the value of i is not captured. By the time the click handler actually is executed (when the click event is triggered in whatever way), the for loop has completed (a long time ago), and the value of i is the final value of the loop. You can capture the value of i with a closure like the above.

Although I know another way of handling, cleaner in my opinion, is to use:

.click(clickHandler(i));

function clickHandler(index) {
    return function (e) {
        onMouseClicked(i, e);
    };
}
Ian
  • 50,146
  • 13
  • 101
  • 111
2

It is because of the closure variable i.

for (var i = 0; i < curNodes.length; i++) {
    (function(i) {
        var node = curNodes[i];
        var obj = paper.rect(node.getX(), node.getY(), node.width,
                node.getHeight()).attr({
                    fill : nodes[i].getColor(),
                    "fill-opacity" : 0.6
                }).click(function(e) {
                    onMouseClicked(i, e);
                });
    })(i);
}
Arun P Johny
  • 384,651
  • 66
  • 527
  • 531