在创建时使用范围内的变量绑定单击处理程序? [英] Bind click handler with variables in scope when created?

查看:58
本文介绍了在创建时使用范围内的变量绑定单击处理程序?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在jQuery中动态创建项目列表,并动态地将单击处理程序绑定到每个项目,并在创建单击处理程序时将变量放在范围内。

I'd like to create a list of items dynamically in jQuery, and dynamically bind a click handler to each one, with the variables in scope at the moment the click handler is created.

下面的代码创建1-6的项目列表,但点击处理程序似乎只与最终项目的值绑定 - 警报始终显示6。

The code below creates a list of items from 1-6, but the click handler only seems to bind with the value of the final item - the alert always shows 6.

这是一个JavaScript范围问题吗?如何使用1-6中的变量绑定警报?

Is this a JavaScript scope problem? How can I bind the alerts with variables from 1-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);      
}   

请参阅jsFiddle: http://jsfiddle.net/n6FU5/

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

推荐答案

这是范围和花括号之间经典的JavaScript混淆。事实证明,花括号与JavaScript中的范围几乎没有关系。范围仅来自函数

This is a classic JavaScript confusion between "scope" and "curly braces". It turns out that curly braces have little to do with scope in JavaScript. Scope only arises from functions.

这样做的一个结果是变量总是被提升到范围的顶部,即最近的函数。所以你的代码完全等同于:

One consequence of this is that variables are always hoisted to the top of the scope, i.e. the nearest function. So your code is exactly equivalent to:

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 ,并且将来每当调用click处理程序,你看到 6

With this in mind, you can see how, since route_num is the same variable every time through the loop, after the loop is over its value is set to 6, and in the future whenever the click handler is called, the 6 is what you see.

解决这个问题的一种方法是包装内容循环在自执行匿名函数中:

One way to fix this is to wrap the contents of your loop in a self-executing anonymous function:

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

这样,当变量被提升时,它们将被提升到该内部自执行函数的顶部,因此每次循环运行时都会有不同的实例。

That way, when the variables get hoisted, they will just get hoisted to the top of that inner self-executing function, and so there will be different instances of them for each run through the loop.

这篇关于在创建时使用范围内的变量绑定单击处理程序?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆