использование setTimeout в javascript для создания простой анимации

#javascript #settimeout

#javascript #settimeout

Вопрос:

Я использую setTimeout для создания анимации в Javascript, но, похоже, это не работает. Выполняется только 1-й ход анимации, никаких последующих ходов.

Я пробовал на двух разных ноутбуках с помощью Firefox, один не выдает никаких ошибок, но один говорит self.animateCallback is not a function . Я также вижу другие ошибки, такие как сообщение о том, что моя функция тайм-аута бесполезна или «компилируется и запускается», когда я пробовал разные способы. Похоже, это не работает. Я пробовал "function(self){self.animateCallback()}" и "self.animateCallback" (с кавычками и без них).

Код приведен ниже, он является частью прототипа метода.

     increment : function(incr, target, tick) {
    var self = this;

    self.animateCallback = function()
    {
        var done = Math.abs(self.currValue - target) < Math.abs(incr);
        if(!self.animateCallback || done) {

            if(done) {
                self.updateAngle(self.currValue/self.maxValue);
                self.stopAnimation(); //just setting animateCallback to null
            }
        }
        else
        {
            self.updateAngle((self.currValue incr)/self.maxValue);
            setTimeout(self.animateCallback, tick);
        }

    }
    self.animateCallback.call();
},
  

Комментарии:

1. Нам нужно было бы просмотреть больше кода, чтобы понять, что не так. Очевидно, что что-то не так с этим, self или self.animateCallback, поскольку в коде не должно быть проблемы, о которой вы сообщаете, если с одним из них не было проблем.

Ответ №1:

У меня такое чувство, что проблема как-то связана со строкой setTimeout(self.animateCallback... , которая обращается к функции через замыкание и свойство. По крайней мере, это должно быть аккуратнее, чтобы сделать это так:

 increment : function(incr, target, tick) {
    var self = this;

    var animateCallback = function()
    {
        var done = Math.abs(self.currValue - target) < Math.abs(incr);
        if(done) {
            self.updateAngle(self.currValue/self.maxValue);
            self.animateTimeout = null;
        }
        else
        {
            self.updateAngle((self.currValue incr)/self.maxValue);
            self.animateTimeout = setTimeout(animateCallback, tick);
        }

    }
    animateCallback();
},
stopAnimation: function() {
    if (this.animateTimeout) {
        clearTimeout(this.animateTimeout);
        this.animateTimeout = null;
    }
},
  

Комментарии:

1. Я также ссылаюсь на строку tt. В предложении ur кажется, что stopAnimation не требуется. Вместо этого я в итоге сделал что-то вроде self.timer = setTimeout(function(obj){obj.animateCallback.call()};), tick, self);

Ответ №2:

Я думаю, ошибка заключается в том, что какой-то другой код изменяет значение self.animateCallback на что-то другое. В первый раз setTimeout имеет правильное значение для self.animateCallback , но после первого раза значение self.animateCallback изменилось на что-то другое, что не является функцией, но по-прежнему является неверным значением, поэтому !self.animateCallback возвращает false .

Вы можете попробовать изменить оператор if на это:

 if((typeof self.animateCallback !== "function") || done) {

    if(done) {
        self.updateAngle(self.currValue/self.maxValue);
        self.stopAnimation(); //just setting animateCallback to null
    }
}
  

Ответ №3:

попробуйте передать анонимную функцию setTimeout , например

 setTimeout(function(){ self.animateCallback(); }, tick);
  

надеюсь, это поможет.

Комментарии:

1. Это не требуется и не будет иметь значения, поскольку self.animateCallback() это уже функция. Не нужна анонимная функция с setTimeout() .