简体   繁体   English

将参数传递给动画回调函数

[英]Pass parameter to animate callback function

I have the following jQuery snippet and I'm trying to pass a parameter to the function of animate method but can't get it right. 我有以下jQuery代码段,我正在尝试将参数传递给animate方法的功能,但无法正确执行。

function move() {

    var points = [13, 8, 5];

    for(var pointIdx=0; pointIdx < points.length-1; pointIdx++) {
        ..
        ..

        // animate move.        
        $('#my_id', gameWindow.document).animate({ left: "50px" ,top:  "50px" }, 1500, 'linear', 
            function(pointIdx) {
                console.log("Animation: Iteration=" + pointIdx); // pointIdx is undefined at this point, why?
               ...
               ...
            }
        )
    }
}

How to do it right? 怎么做对?

Thanks! 谢谢!

pointIdx is undefined because the complete callback for jQuery's animation does not have any parameters available to use. 由于对jQuery动画的完整回调没有可用的任何参数,因此未定义pointIdx

http://api.jquery.com/animate/ http://api.jquery.com/animate/

complete 完成
Type: Function() 类型:Function()
A function to call once the animation is complete. 动画完成后调用的函数。

So when you include the parameter pointIdx in the animate function complete callback like this 因此,当您在动画函数中包含参数pointIdx ,像这样完成回调

function(pointIdx) {

you are overwriting the variable pointIdx . 您正在覆盖变量pointIdx Because JavaScript uses a stack of lexical variable environments, pointIdx is pushed on to the stack with the value passed in from the complete callback. 由于JavaScript使用了一系列词法变量环境,因此pointIdx会使用从完整回调中传入的值压入堆栈。 This value is undefined , and when you try to read the value of the variable pointIdx inside of the execution context of the complete callback, it gets the top most value of the stack, which is undefined . 该值是undefined ,当您尝试在完整回调的执行上下文中读取变量pointIdx的值时,它将获得堆栈中最高的值,即undefined This is why pointIdx is undefined here. 这就是为什么在此处未定义pointIdx原因。

In order to store the value of pointIdx inside of this callback you need to remove it from the parameters, and also you need to close over it with an IIFE. 为了将pointIdx的值存储在此回调中,您需要将其从参数中删除,并且还需要使用IIFE将其关闭。

jsFiddle Demo

for(var pointIdx=0; pointIdx < points.length; pointIdx++) {
    ..
    ..

    // animate move.        
    //close over pointIdx
    (function(pointIdx){
    //now the execution context is inside of the anonymous function
    //and the value of pointIdx in the loop is stored in
    //variable pointIdx (same name for consistency) is at the top of that variable environment
    $('#my_id', gameWindow.document).animate({ left: "50px" ,top:  "50px" }, 1500, 'linear', 
        function() {
            console.log("Animation: Iteration=" + pointIdx); // pointIdx will now contain the iteration value from the for loop
           ...
           ...
        }
    )
    })(pointIdx);
}

The problem is timing - the animation callback happens after 1500 ms, but your for loop completes almost instantly. 问题在于时间安排-动画回调在1500毫秒后发生,但您的for循环几乎立即完成。 You need to rewrite it like this: 您需要像这样重写它:

var points = [13, 8, 5];
var pointIdx = 0;

function animateForPointIndex(index) {
    $('#my_id').animate({
        left: "50px",
        top: "50px"
    }, 1500, 'linear', function () {
        pointIdx++;
        if (pointIdx < points.length) {
            console.log("Animation: Iteration=" + pointIdx);
            // do what you need to here 
            animateForPointIndex(pointIdx);
        }
    });
}
animateForPointIndex(0);

The animate function is called recursively after each completion, only if the point index is less than the length of the points array. 仅当点索引小于points数组的长度时,才会在每次完成后递归调用animate函数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM