我试图在我的阵列上创建一个for循环基地
var lists = [ "a", "b", "c", "d" ];
for ( i = 0; i < lists.length; i++) {
// console.log(lists[i]);
$(".sa-report-btn-"+lists[i] ).click(function () {
$(".sa-hide-"+lists[i]).removeClass("hidden");
$(".sa-report-"+lists[i]).addClass("hidden");
});
$(".sa-hide-btn-"+lists[i]).click(function () {
$(".sa-hide-"+lists[i]).addClass("hidden");
$(".sa-report-"+lists[i]).removeClass("hidden");
});
}
我做得对吗?我得到Uncaught ReferenceError: i is not defined
我可以像这样使用我的jQuery选择器连接每个循环 - &gt; $(".sa-hide-"+lists[i])
?只是好奇......
答案 0 :(得分:25)
首先,听起来你正在使用严格模式 - 好!它让你免于陷害The Horror of Implicit Globals。
代码存在两个问题。
第一个是你错过了i
的声明。您需要在循环上方添加var i;
,例如:
var i;
for ( i = 0; i < lists.length; i++) {
// ...
或
for (var i = 0; i < lists.length; i++) {
请注意,即使在后一个示例中,i
变量在函数范围内,也不限于for
循环。
第二个更精细,概述in this question and its answers:您的click
处理程序将{em}持久引用到i
变量,而不是副本它们的创建地点。因此,当他们针对点击运行时,他们会看到i
为值lists.length
(循环结束时的值)。
在您的情况下,它很容易修复(您不必再声明i
):完全删除循环,并将其替换为Array#forEach
或jQuery.each
:
lists.forEach(function(list) {
$(".sa-report-btn-" + list).click(function () {
$(".sa-hide-" + list).removeClass("hidden");
$(".sa-report-" + list).addClass("hidden");
});
$(".sa-hide-btn-" + list).click(function () {
$(".sa-hide-" + list).addClass("hidden");
$(".sa-report-" + list).removeClass("hidden");
});
});
如果您需要支持真正的旧版浏览器,可以使用Array#forEach
(在2009年添加,作为ECMAScript5的一部分),或者您可以使用$.each
(jQuery.each
)代替:
$.each(lists, function(index, list) {
// Note addition ------^
$(".sa-report-btn-" + list).click(function () {
$(".sa-hide-" + list).removeClass("hidden");
$(".sa-report-" + list).addClass("hidden");
});
$(".sa-hide-btn-" + list).click(function () {
$(".sa-hide-" + list).addClass("hidden");
$(".sa-report-" + list).removeClass("hidden");
});
});
请注意,我们实际上并没有在回调中的任何位置使用index
,但我们必须指定它,因为$.each
调用我们的回调,索引作为第一个参数,值为第二个参数。 (这就是为什么我更喜欢Array#forEach
。)所以我们必须接受两个参数,我们想要的是第二个参数。