循环中的闭包导致我出现问题。我想我必须创建另一个函数来返回一个函数来解决问题,但我无法使用我的jQuery代码。
以下是简化形式的基本问题:
function foo(val) {
alert(val);
}
for (var i = 0; i < 3; i++) {
$('#button'+i).click(function(){
foo(i);
});
}
自然地点击三个按钮中的任何一个都会发出警告说3.我想要的功能是点击按钮1会发出一个警告说1,按钮2会说2等。
我该怎么做呢?
答案 0 :(得分:10)
请参阅bind方法。
$('#button'+i).bind('click', {button: i}, function(event) {
foo(event.data.button);
});
来自文档:
可选的eventData参数是 不常用。提供的时候,这个 参数允许我们传递额外的 处理程序的信息。一个方便 使用此参数是有效的 围绕由闭包引起的问题
答案 1 :(得分:6)
试试这段代码:
function foo(val) {
alert(val);
}
var funMaker = function(k) {
return function() {
foo(k);
};
};
for (var i = 0; i < 3; i++) {
$('#button'+i).click(funMaker(i));
}
这里有一些重点:
i
的每个值都在k
的新范围内复制,而funMaker
返回的函数在k
附近关闭(不是i
在循环中改变),而不是click
(确实如此)。i
的函数不“拥有”i
,而是关闭其{1}}的创建者,{ {1}}循环中的变化。i
内联编写的,但我通常使用这样的帮助函数来使事情更清晰。funMaker
的论点是funMaker
,但没有区别,它可能是k
没有任何问题,因为它存在于函数{{1}的范围内}。编辑:修正了一些标点符号。
答案 2 :(得分:5)
答案 3 :(得分:3)
使用jquery中的.each函数 - 我猜你是一个循环遍历类似的元素 - 所以使用类似的东西添加点击:
$(element).children(class).each(function(i){
$(this).click(function(){
foo(i);
});
});
未经测试但我总是尽可能使用这种结构。
答案 4 :(得分:1)
或者只是制作一个新功能,正如您所描述的那样。它看起来像这样:
function foo(val) {
return function() {
alert(val);
}
}
for (var i = 0; i < 3; i++) {
$('#button'+i).click(foo(i));
}
我很确定Mehrdad的解决方案不起作用。当您看到人们复制到临时变量时,通常会保存“this”的值,这可能在内部子范围内有所不同。