11.3 全局效果属性
jQuery的效果模块中包含一个非常方便的$.fx
对象,在需要彻底改变动画的性质时,可以访问这个问题。尽管这个对象的某些属性名不见经传,只为jQuery库本身使用而设计,但另外一些属性则可以供我们在全局层面上修改动画运行的效果。在接下来的例子中,我们来学习几个文档中有记载的属性。
11.3.1 禁用所有效果
前面我们已经讨论了一种中止当前动画运行的方式,但如果想要完全停止所有动画怎么办?比如说,我们会在默认情况下提供动画,但在一些低配置设备,比如非智能手机上,就需要禁用这些动画;否则,这些设备中的动画就会显得支离破碎。或者,当用户认为动画会分散其注意力时,也应该允许用户关闭动画。为了实现这个功能,只要简单地把$.fx.off
属性设置为true
即可。为了演示这个例子,我们来显示之前隐藏的按钮,以便让用户能够打开或关闭动画,参见代码清单11-4。
代码清单11-4
$('#fx-toggle').show().on('click', function() {
$.fx.off = !$.fx.off;
});
这样,原来隐藏的按钮显示在了介绍性文字与之后的照片之间,如图11-3所示。
图 11-3
当用户单击这个按钮把动画关闭时,接下来的动画——增大和收缩图片都会瞬间完成(持续0毫秒),而任何回调函数也都几乎在瞬间调用完毕。
11.3.2 定义效果时长
$.fx
对象还有一个speeds
属性。这个属性本身是一个对象,包含三个属性,通过jQuery核心源代码中这一小段可以看出来:
speeds: {
slow: 600,
fast: 200,
//默认速度
_default: 400
}
我们知道所有 jQuery 的动画方法都提供了一个可选速度(或持续时间)参数。看看$.fx.speeds
对象,就知道字符串'slow'
和'fast'
分别对应着600毫秒和200毫秒。每次调用一个动画方法,jQuery都要通过以下步骤来确定效果的持续时间。
检测
$.fx.off
是否为true
。如果是则持续时间为0。检测传入的持续时间是否为数值;如果是,则将持续时间设置为该毫秒数。
检测传入的持续时间是否与
$.fx.speeds
的某个属性键匹配。如果是,则将持续时间设置为该属性的值。如果前面检测未发现传入持续时间参数,则将持续时间设置为
$.fx.speeds._default
的值。
现在,我们就明白了:只要传入的持续时间字符串不是'slow'
或'fast'
,那么动画的持续时间就是默认的400毫秒。更进一步,要想添加自定义的速度选项,只要给$.fx.speeds
添加一个属性即可。比如,执行$.fx.speeds.crawl = 1200
这行代码之后,就可以在任何动画方法中使用'crawl'
把动画持续时间设置为1200毫秒:
$(someElement).animate({width: '300px'}, 'crawl');
尽管输入'crawl'
并不比直接写1200更省事儿,但在大型项目中使用自定义速度会更适合那些共享动画速度的情况,因为修改起来很方便。假如需要修改速度,不用在代码里执行查找替换,一处一处地修改,而只要修改$.fx.speeds.crawl
的值即可。
自定义速度当然有用,但更有用的恐怕还得说是修改默认速度了。很简单,修改默认速度就是修改_default
属性的值,参见代码清单11-5。
代码清单11-5
$.fx.speeds._default = 250;
这样,我们就定义了一个新的更快的默认速度,除非我们指定持续时间参数,否则任何新动画都会使用这个默认的速度。为了演示这一点,需要在页面中添加另一个可交互的元素。换句话说,当用户单击人物头像时,要显示每个人的详细信息。为此,我们要制造一种细节信息从头像底下“展开”的假象,也就是让细节信息从头像下面移动出来,直到它们最终的位置。如代码清单11-6所示。
代码清单11-6
$(document).ready(function() {
function showDetails() {
$(this).find('div').css({
display: 'block',
left: '-300px',
top: 0
}).each(function(index) {
$(this).animate({
left: 0,
top: 25 * index
});
});
}
$('div.member').click(showDetails);
});
这样,单击每个人的照片时,就可以调用showDetails()
这个处理函数。这个函数先设置包含细节信息的<div>
元素的起始位置,把它放在每个的头像下面。然后,再把每个元素以动画方式移动到它们的最终位置。通过调用.each()
方法,可以分别计算出每个元素的最终top
位置值。
动画结束后,文本会显示出来,如图11-4所示。
图 11-4
因为.animate()
方法是在两个不同<div>
上分别调用的,所以这两个动画不会排队,而是几乎同时发生。此外,由于并没有指定动画的持续时间,因而使用的是新的默认时间:250毫秒。
再单击其他成员的照片时,应该隐藏之前显示的信息。要想跟踪当前显示的是哪一个成员的详细信息,只要使用一个active
类即可,参见代码清单11-7。
代码清单11-7
var $member = $(this);
if ($member.hasClass('active')) {
return;
}
$('div.member.active')
.removeClass('active')
.children('div').fadeOut();
$member.addClass('active');
新增的代码放在了showDetails()
函数前面,也就是在被单击的成员<div>
中添加active
类。通过找到这个类,很容易确定不可见的元素并将其以动画方式淡出。如果被单击的成员<div>
有这个active
类,那就直接返回,什么也不做了。
注意,调用的.fadeOut()
方法也使用了前面定义的比较快的250毫秒持续时间。这个默认值对jQuery所有的预置效果都是有效的,就像它对前面那个.animate()
方法起作用一样。