开发者

Adding click functions to DOM elements dynamically

开发者 https://www.devze.com 2023-03-21 12:00 出处:网络
In my test code,开发者_如何学C 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

In my test code,开发者_如何学C 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.


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);
}


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);
     });
 });


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');
       }

    });


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>
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号