jQuery animate()回调只记住循环中的最后一个变量

时间:2013-12-01 18:05:40

标签: jquery jquery-animate jquery-callback

我正在编写一个脚本,它基本上每次都会将一个盒子移动到不同的地方并且它会执行指定数量的循环。框的移动只是一个animate()函数,它处于while循环中。

在这个循环中,我们还随机选择应该从哪里回来的坐标。在它到达指定的坐标后,我将div插入到这个确切的位置并使其变为红色。这是我在回调函数中做的。

出现的问题是div只会添加到框所到的最后一个坐标。

var i =0;

while( i<5 ){ //specifying the cycles for the box' movement

var hstandWidth = $("#hstand").width()+27; //getting the current x-coordinates

//array to randomly select x-coordinates from 
var items = Array(hstandWidth-(50)*1, hstandWidth-(50)*2, hstandWidth-(50)*3, hstandWidth-(50)*4, hstandWidth-(50)*5,hstandWidth-(50)*6,hstandWidth-(50)*7,hstandWidth-(50)*8);                                         
//variable with the x-coordinates, which are randomly fetched from the array
var moveLeft = items[Math.floor(Math.random()*items.length)];

//array to randomly select y-coordinates from 
var items2 = Array(30,30*2,30*3,30*4,30*5,30*6,30*7);
//variable with the y-coordinates, which are randomly fetched from the array
var moveTop = items2[Math.floor(Math.random()*items2.length)];

// y-achs movement
$(this).animate({ "top"  : ""+ moveTop  +"px" }, 800);  
// x-achs movement with the callback function which should add the colored div to every position the box has been
$(this).animate({ "left" : ""+ moveLeft +"px" }, 800, function(){

$("<div style='position: absolute; top: "+moveTop+"px; left: "+moveLeft+"px; background: #ffcccc; width: 50px; height: 30px;'></div>").appendTo("#grid");

});                     
//get the box to the initial position
$(this).animate({"left": "0px"}, 800);
$(this).animate({"top" : "0px" }, 800);
//mark cycle passed
i++;

1 个答案:

答案 0 :(得分:1)

每次通过moveTop循环时,moveLeftfor个变量都会被更改,所以当动画完成一段时间之后,您只能看到循环结束时的值动画完成回调。您可以使用这样的闭包在每次循环中冻结值:

var i =0;

while( i<5 ){ //specifying the cycles for the box' movement

    var hstandWidth = $("#hstand").width()+27; //getting the current x-coordinates

    //array to randomly select x-coordinates from 
    var items = Array(hstandWidth-(50)*1, hstandWidth-(50)*2, hstandWidth-(50)*3, hstandWidth-(50)*4, hstandWidth-(50)*5,hstandWidth-(50)*6,hstandWidth-(50)*7,hstandWidth-(50)*8);                                         
    //variable with the x-coordinates, which are randomly fetched from the array
    var moveLeft = items[Math.floor(Math.random()*items.length)];

    //array to randomly select y-coordinates from 
    var items2 = Array(30,30*2,30*3,30*4,30*5,30*6,30*7);
    //variable with the y-coordinates, which are randomly fetched from the array
    var moveTop = items2[Math.floor(Math.random()*items2.length)];

    // y-achs movement
    $(this).animate({ "top"  : ""+ moveTop  +"px" }, 800);  
    // x-achs movement with the callback function which should add the colored div to every position the box has been

    // create closure to capture moveTop and moveLeft values for later callback
    // use different named variables xmoveTop and xmoveLeft to distinguish the
    // closure variable from the outer for loop variable
    (function(obj, xmoveTop, xmoveLeft) {
        $(obj).animate({ "left" : ""+ xmoveLeft +"px" }, 800, function(){

            $("<div style='position: absolute; top: "+xmoveTop+"px; left: "+xmoveLeft+"px; background: #ffcccc; width: 50px; height: 30px;'></div>").appendTo("#grid");

        });
    })(this, moveTop, moveLeft);                     

    //get the box to the initial position
    $(this).animate({"left": "0px"}, 800);
    $(this).animate({"top" : "0px" }, 800);
    //mark cycle passed
    i++;
}