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);
}
上面的 jQuery 部分位于 for 循环内。循环的每次迭代都会执行以下操作:
- 设置跨度的背景
- 使对象具有动画效果
- 完成后,重置跨度的背景
我使用回调函数来重置背景,以便它在执行此操作之前完成动画。但是,它最终只会影响 for 循环中引用的最后一个跨度。
如果我将这段代码移到回调之外,那么它会影响 for 循环的每次迭代中的每个范围(但在这种情况下不会等待动画)
我猜这个问题与在动画函数内的函数内构建选择器有关。我的标记中是否存在一些错误的语法?
编辑(根据 Russ 的建议,我现在在上面的示例中包含完整的循环)
这是将闭包与循环组合时遇到的常见问题。 JavaScript 是一种后期绑定语言,循环不会引入新的作用域。所以:
for (var i= 0; i<5; i++) {
$('#thing'+i).click(function() {
alert(i);
});
}
只有一个i
这段代码中的变量。它开始于0
一旦赋值循环完成,就留在5
。上的点击事件#thing0
元素只会被解雇after循环已完成执行,此时的值i
将5
。您将不会获得定义时间值0
这可能是你所预料到的。
这不仅适用于循环变量本身,也适用于每次循环时重新分配的任何其他变量。所以在你的例子中的值barChartID
动画回调函数内部始终是与循环中最后一个元素关联的 id。
通常的解决方法是使用以下结构在定义时获取循环变量值的副本:does引入一个新的作用域,即另一个函数:
$(barChartID + " img").animate({height: actualBarHeight}, 500, function(barChartID) {
return function() {
$(barChartID + " .value span").css('background-color','white');
};
}(barChartID));
更多关于循环闭包的信息。 https://stackoverflow.com/questions/643542/doesnt-javascript-support-closures-with-local-variables
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)