Why does the alert coming from my loop always return the last value, not each iteration value?
我有一些按钮,存储在一个数组中。 然后我循环遍历该数组,为每个按钮添加一个click事件。 每次单击都会提醒i的值。 我希望值为1,2,3等等,但它们总是以一个值的形式返回,以防3。
你能解释为什么会发生这种情况以及如何解决它吗?
请看这个jsFiddle。 代码如下:
1 2 3 4 5 6 7
| var theButtons = ['.button.one', '.button.two', '.button.three'];
for (i=0; i<theButtons.length; i++) {
$(theButtons[i]).click(function () {
alert(i); // always returns 3
});
} |
请尽可能简单明了地解释它 - 我有点像Javascript和编程的初学者。
-
从stackoverflow.com/questions/2568966/&hellip开始阅读;
-
为什么被问过一千次的问题得到了提升呢?
-
我会说你不想以这种方式对这些事件进行编码......
-
@Alvaro你应该解释为什么他不应该在那里留下这个空洞的评论。
-
作为一个编程,特别是一个javascript初学者,你可能想要开始阅读关闭之前喝一些饮料。 在你开始理解之前,你的大脑会受到一段时间的伤害。
-
@shrewdbeans这对你有用吗?jsfiddle.net/fE55Y/6
-
哇这个问题有最多的答案,我见过的选票...
当您单击按钮i === 3时。需要将i的值传递给闭包:
1 2 3 4 5 6 7
| for (var i = 0; i<theButtons.length; i++) { // do `var i` so the i is not global
(function(index){
$(theButtons[i]).on('click', function () {
alert(index); // index === the value that was passed
});
})(i); // pass the value of i
} |
小提琴演示:http://jsfiddle.net/maniator/fE55Y/3/
-
我想知道downvote的原因?就在我考虑投票之前
-
@roasted哈哈我不知道:-P
-
只有一点,应该注意使用全球"我"。
-
由于在同一个问题的另一个答案中抱怨jQuery,但在这里使用"臃肿的jQuery函数"而被低估了。
-
@roasted固定。
-
.click别名和.onclick别名直接调用.on('click', - 你添加了无用的膨胀。
-
@Loktar那是相当报复的....
-
@Loktar开心吗?...
-
@defaultNINJA是的,但是他在javascript聊天中发布了这个问题给了他的downvote注意力chat.stackoverflow.com/transcript/message/10714138#10714138我最初并不是报复性的。
-
@Loktar我没有要求任何downvote关注。我正在发表评论,正如许多其他人在不需要时使用许多jQuery函数一样。我所做的只是复制/粘贴OP代码并解释错误以及如何解决它。
-
谢谢@Neal,这完美无缺。我想我需要对闭包进行一些研究!
-
@shrewdbeans乐意帮忙:-D
-
谢谢你:)
只需使用EACH方法:
1 2 3 4 5
| $(".button" ).each(function( index ) {
$(this).click( function(e){
alert( index +":" + $(this).text());
});
}); |
小提琴:http://jsfiddle.net/fE55Y/4/
更新:
同意所要求的内容不需要.each()。这是不使用.each()方法的那个。
1 2 3
| $(".button").click(function () {
alert("Button Index:" + $(this).index());
}); |
-
@Neal - 好吧,如果jQuery正在使用,无论如何使用.each()不会增加任何臃肿。
-
@ j08691这个答案是依赖于DOM元素的文本 - 这是没用的?此外,op不是通过所有按钮,但他只是通过一组设置的按钮......
-
他的问题也被标记了......并且已经使用了jQuery。当然你可以用纯JS做到这一点,但没有理由对它进行投票。
-
它正在为处理添加膨胀...而不是它会被注意到,但是Neals评论仍然有点有效。但他对.click别名的使用同样愚蠢。
-
这个答案的问题在于它没有解释原始代码中的问题,这至少是实际问题的一半。
-
@Neal - 哦,我不是说这是正确的答案,我只是说,如果OP使用的是jQuery,我看不到臃肿来自哪里。如果问题没有使用jQuery,这个答案建议它确定,不必要的额外代码基本的东西。
-
Neal,请解释它是如何膨胀的,如果是,为什么jQuery开发人员构建这样的方法?我的主要观点是,如果你想用纯JS风格编写函数,那么jQuery的需求是什么?
-
@Learner这就是为什么数组上有一个普通的.forEach循环。没有真正的理由使用$.each,因为它甚至没有回答OP的问题。
-
@ j08691 ^^见上文。
-
@Neal提问者有一个标签"jQuery"和.foreach是一个纯JS函数而不是jQuery。我看到了标签并为他提供了jQuery解决方案。至于第二部分"我没有回答被问到的问题",这是完全不同的事情,不应该与$ .each对话混淆。
-
@Learner和$(this)选择一遍又一遍的收益?缓存他们!
-
我一直注意到的另一件事是有些人只是在不理解的情况下向下投票,因为有较高投票权的人不相信你的解决方案。
-
@Neal在这个例子中缓存$(this)实际上不会影响性能(如果有的话)。
-
@Neal我没有试图证明我的观点,但不要告诉我,我们现在担心纳秒性能命中。如果它如此重要,那么实际上没有人应该使用jQuery。
-
在这种情况下,你甚至不需要每个人。只需提醒按钮的索引即可。 <5233>
欢迎使用异步编程和全局变量!
你在这里看到的问题是因为在这种情况下i被全局声明,因为任何地方都可以从任何地方访问。
那么,执行脚本时会发生什么:
-
循环遍历类名数组
-
在每次迭代中,将单击绑定到匹配节点,调用您提供的匿名函数
这里的问题是你提供的函数是在你的循环之外执行的(例如,当点击发生时),所以i的值是最后一次迭代中的值,在这种情况下2
-
这里什么都不是"异步"......
-
哈,公平。也许"非程序性"是一个更好的选择
-
在click中注册的回调可以被视为异步调用...