1

Ok, below is my code:

for (var mycounter = currentcanvas.getObjects().length; mycounter > 0; mycounter--) {
    var id = currentcanvas.getObjects().length - mycounter;
    alert(id);
    $("#frontlayers").prepend('<li id="' + id + '" class="layers"></span> Layer ' + (id + 1) + ': ' + "  " + ' </li>');
    $("#" + id).click(function(e) {
        alert(id);
    });
}​

This correctly adds the li with the text "Layer 1" and "Layer 2", but when I click on them the alert is always 2 instead of 0 and 1 accordingly. does anyone know why this is happening? sorry I'm relatively new to jQuery.

clentfort
  • 2,454
  • 17
  • 19
user1745713
  • 781
  • 4
  • 10
  • 16
  • Your problem has the same root cause as the FAQ question here: http://stackoverflow.com/questions/750486/javascript-closure-inside-loops-simple-practical-example. – pimvdb Oct 30 '12 at 23:42
  • cause you keep updating the value of id. maybe store the id somewhere else – nathan hayfield Oct 30 '12 at 23:42
  • 3
    Try `alert(this.id)` - within the click handler `this` will be the clicked element. The problem you're having with the variable `id` is that all of the click handlers you create refer to the same variable as per the question pimvdb linked to (which is not a jQuery issue). – nnnnnn Oct 30 '12 at 23:43
  • this.id worked like a charm. thanks guys! – user1745713 Oct 31 '12 at 00:02

1 Answers1

4

This is a good use for $.each because using a handler function avoids the scope issue you have with the closure on the variable i:

$.each(currentcanvas.getObjects(), function(i, v) {
     var id = i;  // nb: numeric ID fields only allowed in HTML5
     $('<li>', {
         id: id,
         'class': 'layers',
         text: 'Layer ' + (id + 1) + ': '
     }).appendTo('#frontlayers').on('click', function(e) {
         alert(id);
     });
});

That said, since your ID is stored on the clicked element anyway, you could have just used that directly - this.id

Alnitak
  • 334,560
  • 70
  • 407
  • 495