是否可以在两个不同的值之间更改当前运行的jQuery动画的duration
?
我尝试通过直接分配更改duration
,但没有成功:
var timing = { duration: 4000 };
$(document).click(function (e) {
timing.duration = 1000;
});
$('#foo').animate({top:200, left:200}, timing);
...甚至,更改fx.options.duration
中的step
- 方法不会影响正在运行的动画:
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
}
});
这是一个 fiddle 。 任何想法如何做到这一点?
答案 0 :(得分:10)
持续时间按值传递,而不是通过引用传递。因此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})
}
}
});
答案 1 :(得分:0)
我可能有点迟到,但是因为我在尝试做同样的事情时最终到了这里,其他人也可能。
在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毫秒几乎无法察觉),而不是让它过早停止。