这是一个普遍的问题。
如果我在元素#elm上有一个jQuery动画,我可以使用$('#elm').stop()
通常动画会有一个很好的easeIn,easeOut(就像默认的'swing')。打电话'停止()'立即停止,当场,看起来有点笨重。调用$('#elm').stop(true,true)
使其立即完成动画,一直到终点。
是否有通用方法告诉元素“更改正在运行的动画,以便它'很快'和'附近'停止,但使用首先定义的easeOut”?
好奇, * -pike
答案 0 :(得分:5)
我不知道做一个“gentle_stop”的完全通用的方法 - 一个可以在任何动画上运行的方式,无论它是如何被初始化的。
下面的代码定义了函数gentleStoppable()
,它实际上是jQuery自己的.animate( properties, options )方法的4参数版本。额外的两个参数指定了“平缓 - 停止”阶段。
这是功能:
function gentleStoppable($jQ, animProps, animOptions, stopProps, stopOptions) {
var namespace = 'gentleStop';
var dfltStopOptions = {
duration: 'slow',//override with stopOptions.duration .
easing: 'easeOutCubic',//override with stopOptions.easing . (See also the safety check applied after extending dfltStopOptions below).
queue: namespace
};
animProps = animProps || {};
animOptions = animOptions || {};
stopProps = stopProps || {};
stopOptions = stopOptions || {};
$jQ.each(function(i, elem) {
var $elem = $(elem);
function killCustomEvent() { $elem.off(namespace); }
var C = $.Callbacks('once').add(killCustomEvent);
if(animOptions.complete) {
C.add(animOptions.complete);
}
animOptions.complete = C.fire;
stopProps = $.extend({}, animProps, stopProps);
stopOptions = $.extend({}, animOptions, dfltStopOptions, stopOptions);
stopOptions.easing = ($.easing && $.easing[stopOptions.easing] ) ? stopOptions.easing : 'swing';//just in case what's specifified is unavailable.
$elem.on(namespace, function() {//custom event
killCustomEvent();
C.remove(killCustomEvent);//prevent killCustomEvent being called twice.
$elem.stop(true,false).animate(stopProps, stopOptions).dequeue(namespace);
}).animate(animProps, animOptions);
});
}
启动一个gentleStoppable动画,如下所示:
var animProps = {
left: '300px'
};
var animOptions = {
duration: 2000,
complete: function() {
console.log('complete');
}
};
var stopProps = {
left: '+=15px'
};
var stopOptions = {
duration: 500,
};
gentleStoppable($e1, animProps, animOptions, stopProps, stopOptions);
然后轻轻地停下来:
$("#elem").trigger('gentleStop');
目前,功能并不完美,我只通过有限的测试。以下是已知的问题/改进:
方向:xxx:+=15px
形式的stopProps属性将在softstop阶段无条件地添加15px,即使它处于错误的方向。例如,如果相应的animProps属性为xxx:30px
,则+=15px
将假定从下方接近目标值30px
。类似地,值-=15px
将假设从上方接近相应的目标值。对gentleStoppable()的改进将自动调整每个stopProps属性,以允许从低于或高于上方接近其相应的animProps属性。
Overshoot:xxx:+=15px
形式的stopProps属性将无条件地在reststop阶段添加15px,即使+ 15px使得温和动画超出相应animProps属性中指定的值。如果动画在其自然结束附近停止,则会发生这种情况。对gentleStoppable()的改进会自动阻止每个stopProps的属性导致其超出相应的animProps属性。
自动计算:一个毫无疑问的改进是gentleStoppable()根据animProp计算自身的stopProps值。这将使函数通用,更易于使用,并且正确编写将有效地修复方向和过冲问题。
稍微考虑一下,代码可以重构为jQuery插件,这样会更方便,因为它允许方法链接并避免相当笨拙的.trigger(...)
执行轻柔停止。
如果这有用,请使用它。