1

In my test code, I have a simple div that I'm using as a container for 5 loop created div elements. I try adding a click function to all 5 div elements, but only the last one is given a click function.

<div id="testbed"></div>

<script type="text/javascript">
$(document).ready(function () {
    for (i = 0; i < 5; i++) {
        $("#testbed").html($("#testbed").html() + "<div id='" + i + "'>Hello!</div>");
        $("#" + i).click(function () {
            alert(i);
        });
    }
});
</script>

Interestingly enough, instead of alerting 4, it alerts 5. I don't know why it's only applying the click function to the last div element and not the first 4.

1
  • Hey, I appreciate the time that you guys put into this. A few of you have already posted working examples, and I'll be going through each response carefully, since you all used different examples. Thanks for the help. Commented Jul 20, 2011 at 14:19

4 Answers 4

2

All of your click handlers are sharing the same i variable.
Since, after the loop, i is 5, they all say 5.

You need to create each handler in a separate function that takes i as a parameter, so that each handler will get its own i.

For example:

function buildElement(i) {
    $("#testbed").html($("#testbed").html() + "<div id='" + i + "'>Hello!</div>");
    $("#" + i).click(function () {
        alert(i);
    });
}


for (i = 0; i < 5; i++) {
    buildElement(i);
}
Sign up to request clarification or add additional context in comments.

4 Comments

How would that look like? Do I literally just create a new function outside of that loop, and loop through those div elements adding click functions?
With that example, it still doesn't add the click function to the other divs.
By re-setting the HTML, you're clearing any state in the DOM elements, including event handlers. You should call append() instead.
Also, you should build the DOM element with jQuery and add the handler to it before appending, and not use an ID. (IDs, by the way, cannot start with a number)
0

You could also do something to this effect:

$.each([1, 2, 3, 4, 5], function(index, value) { 
     $("#testbed").append("<div id='" + index + "'>Hello!</div>");
     $("#" + index).click(function () {
         alert(index);
     });
 });

1 Comment

This was the first working example that I came across. Thanks a lot.
0

You need to add the click event to the object.

    $(function(){

      $('#testbed').empty();       

     for (i = 0; i < 5; i++) {
          $('<div />').text('Hello').attr('id', i).click(function(){
              alert($(this).attr('id'));
          }).appendTo('#testbed');
       }

    });

Comments

0

The following is called a javascript closure. At the moment of binding, you run the anonymous function that returns another function that does alert(i) when the event is fired. The first anonymous function "wraps" creates another level of variable scope for the i, so when the original i is incremented later on, the i inside the anonymous function remains untouched. Nifty little trick.

<div id="testbed"></div>

<script type="text/javascript">
$(document).ready(function () {
    for (i = 0; i < 5; i++) {
        $("#testbed").html($("#testbed").html() + "<div id='" + i + "'>Hello!</div>");
        $("#" + i).click(function (i) {
            return function(evt) {
                // inside here, you have access to the event object too
                alert(i);
            };
        }(i));
    }
});
</script>

More information at javascript closures

Btw if you wish to add click events to all divs, you can't replace them with .html() in every loop, use .append() instead, like so:

<div id="testbed"></div>

<script type="text/javascript">
$(document).ready(function () {
    for (i = 0; i < 5; i++) {
        $("#testbed").append("<div id='" + i + "'>Hello!</div>");
        $("#" + i).click(function (i) {
            return function(evt) {
                // inside here, you have access to the event object too
                alert(i);
            };
        }(i));
    }
});
</script>

2 Comments

This example didn't work. It only added a click function to the last div item.
I mean, I'm the only responder who gave you the correct solution, not a workaround.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.