#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()
.