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/.

2

3 Answers 3

2

Since you are using a closure scoped variable in a loop, inside the loop you need to create a private closure.

$('#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)
    }
});
Sign up to request clarification or add additional context in comments.

Comments

0

Seems like you run into closures issue, try this:

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

This will create immediate invoked function that will closure your variable i so you can use it in future. For now you just overriding i variable in your for-loop so you will have always same value that will equal last for-loop iteration.

Comments

0

Don't make functions within a loop.

DEMO

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

Comments

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.