Tell me more ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

I am trying to figure this out. I have 3 buttons id (test1, test2, test3) in my HTML! In my jQuery I have an click function in a for loop like this:

$(document).ready(function() {
    for (var i = 0; i < 3; i++) {
        $("#test"+i).on('click', function() {
            alert("I am clicked! ("+i+")");
        });
    }  
});

Now, I am alerting a message for each of them, nut all the (i) in the alert is giving the last number "3"... How do i get it to write "I am clicked (1)" if I press test1 and equally if I press test2 and test3?

I have a jsfiddle to explain here.

Hoping for help and thanks in advance ;-)

share|improve this question

2 Answers

The problem is that the handlers you're assigning have an enduring reference to the i variable, not a copy of that variable as of when the function was created. They're closures over the i variable (and other things). More: Closures are not complicated

There are several ways to solve this.

  1. You can put a piece of information on the elements so they can all share a single handler, which is probably preferred. (You actually already have that information in your example, we can figure out i from the elements' id values, but I'm assuming in the real world things are more complex.)

    $(document).ready(function() {
        for (var i = 0; i < 3; i++) {
            $("#test"+i).attr("data-index", i).click(clickHandler);
        }  
    
        function clickHandler() {
            alert("I am clicked! ("+this.getAttribute("data-index")+")");
            // Or:
            alert("I am clicked! ("+$(this).attr("data-index")+")");
        }
    });
    

    Note how we have just one handler function, and it handles clicks on all of the elements.

    Using a single handler may also mean you can take advantage of event delegation, hooking the click on an ancestor element rather than on each of these individual elements, e.g.:

    $("selector for ancestor").on("click", "[id^=test]", ...);
    
  2. You can use a builder function to create the click handlers so that they close over something that doesn't change (an argument we pass to the builder):

    $(document).ready(function() {
        for (var i = 0; i < 3; i++) {
            $("#test"+i).on('click', buildHandler(i));
        }  
    
        function buildHandler(index) {
            return function() {
                alert("I am clicked! ("+index+")");
            };
        }
    });
    
share|improve this answer

Try something like this

$(document).ready(function() {
for (var i = 0; i < 3; i++) {
    $("#test"+i).on('click', function() {
       var value = $(this).attr('id');
           value=value.replace("test", "");
           value=parseInt(value)+1;
        alert("I am clicked! ("+value+")");
    });
}  
});
share|improve this answer
who's giving minus give what wrong on my code – srini 8 mins ago

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.