在动画制作过程中更改jQuery的动画持续时间

是否可以在两个不同的值之间更改当前运行的jQuery动画的duration

我试图通过直接分配来改变duration ,但没有成功:

 var timing = { duration: 4000 }; $(document).click(function (e) { timing.duration = 1000; }); $('#foo').animate({top:200, left:200}, timing); 

…甚至,在step方法中更改fx.options.duration不会影响正在运行的动画:

 var state = false, $(document).click(function (e) { state = true; }); $('#foo').animate({top:200, left:200}, { duration: 4000, step: function(now, fx){ if(state) fx.options.duration = 1000; console.log(fx.options.duration); // 1000 } }); 

这是一个小提琴 。 有什么想法可以做到这一点?

持续时间按值传递,而不是通过引用传递。 因此, animate不会存储duration的引用。 即使您更新选项对象(通过引用传递),jQuery也会在内部使用options.duration ,这意味着它将按值传递。

作为快速修复,您可以停止动画并使用新的持续时间重新启动它 – 调整已经结束的动画部分。

您需要考虑您希望它的行为方式,例如,当您在3秒后将4秒动画加速到2秒动画时。 在下面的代码中,动画将立即生效。 考虑一下,这可能不是你想要的,因为你可能真的关心速度,而不是持续时间。

下面的代码是粗略的草图,我不确定它是否准确,如果它在减少动画值或如何处理多个动画值时起作用。 您也可以只更改一次持续时间。

 var state = false, duration = 8000; $(document).click(function (e) { state = true; duration = 1000; }); var animationCss = {top:200, left:200}; $('#foo').animate(animationCss, { duration: duration, step: function(now, fx){ if(state) { $("#foo").stop(); var percentageDone = (fx.now - fx.start) / (fx.end - fx.start) var durationDone = fx.options.duration * percentageDone; var newDuration = duration - durationDone; if (newDuration < 0) { newDuration = 0; } $("#foo").animate(animationCss, { duration: newDuration}) } } }); 

http://fiddle.jshell.net/5cdwc/3/

我可能有点迟到,但是因为我在尝试做同样的事情时最终到了这里,其他人也可能。

start()回调中,jQuery将动画对象作为参数传递,因此您只需将引用保留在某处,然后就可以在step()回调中更改它。

就像是 :

 var animEnd = false; //this will be updated somewhere else var animObj; $().animate({ width: '100%' }, { start: function(animation){ animObj = animation; }, step: function(now, tween){ if(!animEnd) //jquery set an interval of 13 but let's be safe animObj.duration += 30; //you can change the value of tween.pos aswell } } ); 

现在棘手的部分是jQuery决定在调用step()回调之前停止或继续动画。 因此,持续时间设置为下一个刻度,如果未设置得足够大,则可以停止动画。
jQuery使用setInterval() ,间隔为13,所以理论上step()应该每13ms调用一次,但由于没有任何保证,我认为持续时间应该至少增加30ms。
我个人甚至会去至少100个。更好的动画有点太长(100毫秒几乎无法察觉),而不是让它过早停止。