0

I am calling initListeners to attach listeners to a number of elements with a r#c# ID. The event should trigger a call to another function which takes two parameters identifying the elements r# and c#.

For some reason, I only get 8:8 out of this for all cells... My guess is that it's a referencing issue. Can anyone suggest a fix?

ModelBoard.prototype.initListeners = function() {

    var r=0, c=0;

    for(r=0;r<=7;r++) {
        for(c=0;c<=7;c++) {
            $("#r" + r + "c" + c).click(function(){
                board.click(r, c);
            });
        }
    }
}

ModelBoard.prototype.click = function(r,c) {
    alert(r + ":" + c);
}
Searle
  • 341
  • 4
  • 16
  • It is because if shared closure variable... https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Closures#Creating_closures_in_loops.3A_A_common_mistake – Arun P Johny Mar 04 '15 at 07:11

1 Answers1

1

Even though the described problem is a duplicate of JavaScript closure inside loops – simple practical example

Without changing any markup, you can do something like

ModelBoard.prototype.initListeners = function () {

    function clickHandler() {
        var match = this.id.match(/r(\d+)c(\d+)/);
        board.click(match[1], match[0]);
    }

    var r, c;

    for (r = 0; r <= 7; r++) {
        for (c = 0; c <= 7; c++) {
            $("#r" + r + "c" + c).click(clickHandler);
        }
    }
}

ModelBoard.prototype.click = function (r, c) {
    alert(r + ":" + c);
}

A more appropriate solution will be add a common class(like rc) to all those elements that need to be targeted by the click handler and use that class to select those elements

ModelBoard.prototype.initListeners = function () {
    $(".rc").click(function () {
        var match = this.id.match(/r(\d+)c(\d+)/);
        board.click(match[1], match[0]);
    });
}
Community
  • 1
  • 1
Arun P Johny
  • 384,651
  • 66
  • 527
  • 531