jquery回调函数仅适用于最后一个循环

前端之家收集整理的这篇文章主要介绍了jquery回调函数仅适用于最后一个循环前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
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循环中引用的最后一个span.

如果我在回调之外移动那段代码,那么它会在for循环的每次迭代中影响每一个跨度(但在这种情况下不等待动画)

我猜这个问题与构建选择器INSIDE函数INSIDE animate函数有关.我的标记中有一些错误的语法吗?

编辑(根据Russ的建议,我现在包括上面示例中的完整循环)

解决方法

这是将闭包与循环组合时遇到的常见问题. JavaScript是一种后期绑定语言,循环不会引入新的范围.所以:
for (var i= 0; i<5; i++) {
    $('#thing'+i).click(function() {
        alert(i);
    });
}

代码中只有一个i变量.它从0开始,一旦赋值循环结束,则保留为5.#thing0元素上的click事件仅在循环执行完毕后才会被触发,此时i的值将为5.您将无法获得您可能期望的define-time值0.

这不仅适用于循环变量本身,也适用于每次循环时重新分配的任何其他变量.因此,在您的示例中,动画回调函数中barChartID的值将始终是与循环中最后一个元素关联的id.

通常的解决方法是通过使用引入新范围的结构(即另一个函数)在define-time获取循环变量值的副本:

$(barChartID + " img").animate({height: actualBarHeight},function(barChartID) {
    return function() {
        $(barChartID + " .value span").css('background-color','white');
    };
}(barChartID));

More on looped closures.

猜你在找的jQuery相关文章