Bind click handler with variables in scope at creation?

I would like to create a list of elements dynamically in jQuery and dynamically bind the click handler to each of them with variables in the area at the time the click handler was created.

The code below creates a list of elements from 1-6, but only the click handler seems to bind to the value of the final element - the warning always shows 6.

Is this a JavaScript visibility issue? How to associate warnings with variables from 1 to 6?

HTML:

<ul id="saved-list">
</ul>

JS:

var all_cookies = [1,2,3,4,5,6];
for (var i = 0; i < all_cookies.length; i++) {
    var route_num = all_cookies[i]; 
    var list_item = "<li><a href='#saved-route'>";
    list_item += "<p>" + route_num + "</p></a></li>";
    var newLi = $(list_item);
    newLi.bind('click', function(){
        alert(route_num);
    });
    $('#saved-list').append(newLi);      
}   

See jsFiddle here: http://jsfiddle.net/n6FU5/

+3
source share
3 answers

JavaScript "" " ". , JavaScript. .

, , .. . , :

var all_cookies = [1,2,3,4,5,6];
var i;
var route_num;
var list_item;
var newLi;

for (i = 0; i < all_cookies.length; i++) {
    route_num = all_cookies[i]; 
    list_item = "<li><a href='#saved-route'>";
    list_item += "<p>" + route_num + "</p></a></li>";
    newLi = $(list_item);
    newLi.bind('click', function(){
        alert(route_num);
    });
    $('#saved-list').append(newLi);      
}   

, , route_num - , 6, , , 6 - , .

, :

var all_cookies = [1,2,3,4,5,6];
for (var i = 0; i < all_cookies.length; i++) {
    (function () { 
        var route_num = all_cookies[i]; 
        var list_item = "<li><a href='#saved-route'>";
        list_item += "<p>" + route_num + "</p></a></li>";
        var newLi = $(list_item);
        newLi.bind('click', function(){
            alert(route_num);
        });
        $('#saved-list').append(newLi);      
    }());
} 

, , , .

+5

, , , onclick route_num . route_num - , 6, . , route_num for.

- , . , , .

var all_cookies = [1,2,3,4,5,6]; 
for (var i = 0; i < all_cookies.length; i++) { 
    var route_num = all_cookies[i];  

    var list_item = "<li><a href='#saved-route'>"; 
    list_item += "<p>" + route_num + "</p></a></li>"; 
    var newLi = $(list_item);

    var fn = new Function("alert('" + route_num + "');");
    newLi.bind('click', fn); 

    $('#saved-list').append(newLi);       
}
+2

This is because of how javascript works. Variables in the ARE scope are available, as you find out, but they are not separate instances for each sub-scope. Therefore, your IS 6 variable value when calling the handler function.

The solution is to store route_numthe data in the attribute and get it inside the click handler.

var all_cookies = [1, 2, 3, 4, 5, 6];

for (var i = 0; i < all_cookies.length; i++) {
    var route_num = all_cookies[i];
    var list_item = "<li><a href='#saved-route'>";
    list_item += "<p>" + route_num + "</p></a></li>";

    var newLi = $(list_item);
    newLi.data('routenum', route_num);
    newLi.bind('click', function() {
        alert($(this).data('routenum'));
    });

    $('#saved-list').append(newLi);
}

Here is your fixed fiddle: http://jsfiddle.net/n6FU5/1/

+1
source

All Articles