创建时将单击处理程序与作用域中的变量绑定
Bind click handler with variables in scope when created?
我想在jQuery中动态创建一个项目列表,并将一个点击处理程序动态绑定到每个项目,在创建点击处理程序时,变量在作用域中。
下面的代码创建了一个1-6项的列表,但点击处理程序似乎只与最终项的值绑定——警报总是显示6。
这是JavaScript范围的问题吗?如何将警报与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/
这是JavaScript中"scope"answers"大括号"之间的典型混淆。事实证明,大括号与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);
}());
}
这样,当变量被提升时,它们将被提升到内部自执行函数的顶部,因此每次运行循环都会有不同的实例。
您遇到的问题是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 = "<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);
}
这是因为javascript的工作方式。正如您所发现的,作用域中的变量是可访问的,但它们不是每个子作用域的单独实例。因此,在调用处理程序函数时,变量的值为IS6。
解决方案是将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 = "<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);
}
这是你固定的小提琴:http://jsfiddle.net/n6FU5/1/
- 当我更新另一个作用域变量时,作用域变量会自动更新
- 如何在隔离作用域指令中访问此作用域变量
- 正在向构造函数添加作用域变量
- 如何在angularjs中将多个作用域变量传递到自定义指令中
- 作用域变量未从状态父控制器继承到子控制器
- 插槽:访问作用域变量
- 在另一个作用域变量中使用AngularJS作用域变量
- 在Angular.js中通过检查作用域变量进行过滤
- 如何更新作为属性传入的作用域变量
- Node.js中的垃圾收集作用域-变量将保持设置状态多长时间
- 从$http.get调用更新Angular作用域变量
- AngularJS ui路由器:访问子作用域变量
- 访问AngularJS中函数中的作用域变量
- 为什么Angular 1.5双向绑定在将作用域变量传递给组件绑定时失败
- 修改作用域变量后,未更新作用域绑定
- 控制器作用域变量在刷新之前未加载
- 将Angular作用域变量的字符串描述传递给指令
- 将内部作用域变量绑定到外部“模板”
- 无法在 $.post 回调中设置作用域变量
- 如何从在 JS 中用作参数的匿名函数中分配外部作用域变量