在创建时使用范围内的变量绑定单击处理程序?

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

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

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

HTML:

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 = "
  • "; list_item += "

    " + route_num + "

  • "; var newLi = $(list_item); newLi.bind('click', function(){ alert(route_num); }); $('#saved-list').append(newLi); }

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

    这是“范围”和“花括号”之间的经典JavaScript混淆。 事实certificate,花括号与JavaScript中的范围几乎没有关系。 范围仅来自function

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

     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 = "
  • "; list_item += "

    " + route_num + "

  • "; newLi = $(list_item); newLi.bind('click', function(){ alert(route_num); }); $('#saved-list').append(newLi); }

    考虑到这一点,你可以看到,因为每次循环时route_num都是相同的变量,循环结束后它的值被设置为6 ,并且将来无论何时调用click处理程序, 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 = "
  • "; list_item += "

    " + route_num + "

  • "; var newLi = $(list_item); newLi.bind('click', function(){ alert(route_num); }); $('#saved-list').append(newLi); }()); }

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

    您遇到的问题是您的onclick函数在单击链接时返回变量route_num的值。 route_num是一个全局变量,当循环结束运行时,该值保持为6。 所以你需要做的是设置函数以在for循环运行时警告route_num的值。

    这样做的方法是将函数构造为字符串,以便您可以将字符串的值附加到函数定义。 这是我认为你想要完成的一个例子。

     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 = "
  • "; list_item += "

    " + route_num + "

  • "; var newLi = $(list_item); var fn = new Function("alert('" + route_num + "');"); newLi.bind('click', fn); $('#saved-list').append(newLi); }

    这是因为javascript的工作方式。 范围内的变量可以在您找到时访问,但它们不是每个子范围的单独实例。 因此,在调用处理函数时,变量的值为IS 6。

    解决方案是在数据属性中保存route_num并在单击处理程序中检索它。

     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 = "
  • "; list_item += "

    " + route_num + "

  • "; var newLi = $(list_item); newLi.data('routenum', route_num); newLi.bind('click', function() { alert($(this).data('routenum')); }); $('#saved-list').append(newLi); }

    这是你固定的小提琴: http : //jsfiddle.net/n6FU5/1/