派克,
我不知道有一种完全通用的方法来执行“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');
演示
就目前而言,该功能并不完美,我只对其进行了有限的测试。以下是已知问题/改进:
方向:表单的一个 stopProps 属性xxx:+=15px
会在柔和停止阶段无条件地增加 15px,即使它的方向是错误的。例如,如果相应的 animProps 属性是,xxx:30px
则+=15px
假定目标值30px
是从下方接近的。同样, 的值-=15px
将假定从上方接近相应的目标值。对gentleStoppable() 的改进将自动调整每个stopProps 属性,以允许从下方或上方接近其对应的animProps 属性。
Overshoot:表单的 stopProps 属性xxx:+=15px
将在柔和停止阶段无条件添加 15px,即使 +15px 使柔和动画超出相应 animProps 属性中指定的值。如果动画在其自然结束附近停止,则往往会发生这种情况。对gentleStoppable() 的改进将自动防止每个stopProps 的属性导致其相应的animProps 属性被超出。
自动计算:一个毫无疑问的改进是,gentleStoppable() 可以根据 animProps 为自己计算 stopProps 值。这将使函数更通用,更易于使用,并且正确编写,将有效地解决方向和过冲问题。
稍加考虑,代码可以重构为一个 jQuery 插件,这将更方便,因为它允许方法链接并避免相当笨拙.trigger(...)
的执行温和的停止。
如果这有任何用处,那么请使用它。