for(var i=0; i<barValues.length; i++) {
actualBarHeight = Math.floor((barValues[i]/chartMaxY)*barchartHeight);
var barChartID = "#barChart" + (i+1)
$(barChartID + " .value span").css('background-color','transparent');
$(barChartID + " img").animate({
height: actualBarHeight
}, 500, function(){$(barChartID + " .value span").css('background-color','white');}
);
$(barChartID + " .value span").html("$"+Math.floor(barValues[i]));
$(barChartID + " .value").css("bottom",actualBarHeight+"px");
$(barChartID + " .ylabel").html(chartMaxY);
};
Run Code Online (Sandbox Code Playgroud)
上面的jQuery位于for循环中.循环的每次迭代执行以下操作:
我正在使用回调函数来重置背景,因此在完成动画之前完成动画.但是,它最终只会影响for循环中引用的最后一个span.
如果我在回调之外移动那段代码,那么它会在for循环的每次迭代中影响每一个跨度(但在这种情况下不等待动画)
我猜这个问题与构建选择器INSIDE函数INSIDE animate函数有关.我的标记中有一些错误的语法吗?
编辑(根据Russ的建议,我现在包括上面示例中的完整循环)
bob*_*nce 16
这是将闭包与循环组合时遇到的常见问题.JavaScript是一种后期绑定语言,循环不会引入新的范围.所以:
for (var i= 0; i<5; i++) {
$('#thing'+i).click(function() {
alert(i);
});
}
Run Code Online (Sandbox Code Playgroud)
i
此代码中只有一个变量.0
一旦完成赋值循环,它就开始了5
.#thing0
元素上的click事件只有在循环执行完毕后才会被触发,此时的值i
将是5
.您将无法获得0
您可能期望的define-time值.
这不仅适用于循环变量本身,也适用于每次循环时重新分配的任何其他变量.因此,在您的示例中barChartID
,动画回调函数内部的值将始终是与循环中最后一个元素关联的id.
通常的解决方法是通过使用一种结构,以采取在限定时间的循环变量的值的副本确实引入一个新的范围,即另一种功能:
$(barChartID + " img").animate({height: actualBarHeight}, 500, function(barChartID) {
return function() {
$(barChartID + " .value span").css('background-color','white');
};
}(barChartID));
Run Code Online (Sandbox Code Playgroud)
这是因为您的回调函数具有指向该barChartID
变量的隐式指针。这就是闭包的工作方式。您想要的是barChartID
在每次迭代中创建当前值的新副本。解决此问题的一种模式是for
在函数内运行循环体。我在 John Resig 即将出版的《JavaScript 忍者的秘密》一书中看到了这种模式
for(var i=0; i<barValues.length; i++) function(i){
...
}(i);
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
6021 次 |
最近记录: |