1

I would like to create some objects dynamically and bind events to them (not important what events).

I'm passing a number to the event in order to distinguish those items. There is my code:

$('#add_btn').click(function() {
    var cont = $('#buttons');

    for(var i=0; i<5; i++) {
        var new_btn = $('<input>').attr('type', 'button').val(i);

        new_btn.click(function() {
            alert(i);
        });

        cont.append(new_btn);
    }
});

When I click on any from newly created buttons, displayed number is 5.

I think that i variable is passing by reference, but the question is: how to avoid passing variable by reference? More, even if I crate new variable before binding event (so the reference should point to another object, for example new_val = i.toString()), value is still same for all buttons (then its 4, understandable).

I know that I can attach new_btn.data() and read it in event, but I'm not sure if it won't be an overhead.

Link to jsfiddle: http://jsfiddle.net/Jner6/5/.

4

3 回答 3

2

由于您在循环中使用闭包 范围变量,因此在循环内您需要创建一个私有闭包。

$('#add_btn').click(function () {
    var cont = $('#buttons');

    for (var i = 0; i < 5; i++) {
        (function (i) {
            var new_btn = $('<input>').attr('type', 'button').val(i);

            new_btn.click(function () {
                alert(i);
            });

            cont.append(new_btn);
        })(i)
    }
});
于 2013-11-05T11:52:52.840 回答
0

好像你遇到了闭包问题,试试这个:

(function( i ) {
    new_btn.click(function() {
        alert(i);
    });
})( i );

这将创建立即调用的函数,该函数将关闭您的变量i,以便您将来可以使用它。现在,您只需在 for 循环中覆盖i变量,因此您将始终拥有与上次 for 循环迭代相同的值。

于 2013-11-05T11:53:33.603 回答
0

不要在循环中创建函数。

演示

var cont = $('#buttons');

$('#add_btn').click(function() {

    for(var i=0; i<5; i++) {
      $('<input>', {type:'button', value:i}).appendTo( cont );
    } 

});

cont.on('click', ':button', function() {
    alert( this.value );
});
于 2013-11-05T11:57:50.137 回答