11.3 全局效果属性

jQuery的效果模块中包含一个非常方便的$.fx对象,在需要彻底改变动画的性质时,可以访问这个问题。尽管这个对象的某些属性名不见经传,只为jQuery库本身使用而设计,但另外一些属性则可以供我们在全局层面上修改动画运行的效果。在接下来的例子中,我们来学习几个文档中有记载的属性。

11.3.1 禁用所有效果

前面我们已经讨论了一种中止当前动画运行的方式,但如果想要完全停止所有动画怎么办?比如说,我们会在默认情况下提供动画,但在一些低配置设备,比如非智能手机上,就需要禁用这些动画;否则,这些设备中的动画就会显得支离破碎。或者,当用户认为动画会分散其注意力时,也应该允许用户关闭动画。为了实现这个功能,只要简单地把$.fx.off属性设置为true即可。为了演示这个例子,我们来显示之前隐藏的按钮,以便让用户能够打开或关闭动画,参见代码清单11-4。

代码清单11-4

  1. $('#fx-toggle').show().on('click', function() {
  2. $.fx.off = !$.fx.off;
  3. });

这样,原来隐藏的按钮显示在了介绍性文字与之后的照片之间,如图11-3所示。

11.3 全局效果属性 - 图1

图 11-3

当用户单击这个按钮把动画关闭时,接下来的动画——增大和收缩图片都会瞬间完成(持续0毫秒),而任何回调函数也都几乎在瞬间调用完毕。

11.3.2 定义效果时长

$.fx对象还有一个speeds属性。这个属性本身是一个对象,包含三个属性,通过jQuery核心源代码中这一小段可以看出来:

  1. speeds: {
  2. slow: 600,
  3. fast: 200,
  4. //默认速度
  5. _default: 400
  6. }

我们知道所有 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毫秒:

  1. $(someElement).animate({width: '300px'}, 'crawl');

尽管输入'crawl'并不比直接写1200更省事儿,但在大型项目中使用自定义速度会更适合那些共享动画速度的情况,因为修改起来很方便。假如需要修改速度,不用在代码里执行查找替换,一处一处地修改,而只要修改$.fx.speeds.crawl的值即可。

自定义速度当然有用,但更有用的恐怕还得说是修改默认速度了。很简单,修改默认速度就是修改_default属性的值,参见代码清单11-5。

代码清单11-5

  1. $.fx.speeds._default = 250;

这样,我们就定义了一个新的更快的默认速度,除非我们指定持续时间参数,否则任何新动画都会使用这个默认的速度。为了演示这一点,需要在页面中添加另一个可交互的元素。换句话说,当用户单击人物头像时,要显示每个人的详细信息。为此,我们要制造一种细节信息从头像底下“展开”的假象,也就是让细节信息从头像下面移动出来,直到它们最终的位置。如代码清单11-6所示。

代码清单11-6

  1. $(document).ready(function() {
  2. function showDetails() {
  3. $(this).find('div').css({
  4. display: 'block',
  5. left: '-300px',
  6. top: 0
  7. }).each(function(index) {
  8. $(this).animate({
  9. left: 0,
  10. top: 25 * index
  11. });
  12. });
  13. }
  14. $('div.member').click(showDetails);
  15. });

这样,单击每个人的照片时,就可以调用showDetails()这个处理函数。这个函数先设置包含细节信息的<div>元素的起始位置,把它放在每个的头像下面。然后,再把每个元素以动画方式移动到它们的最终位置。通过调用.each()方法,可以分别计算出每个元素的最终top位置值。

动画结束后,文本会显示出来,如图11-4所示。

11.3 全局效果属性 - 图2

图 11-4

因为.animate()方法是在两个不同<div>上分别调用的,所以这两个动画不会排队,而是几乎同时发生。此外,由于并没有指定动画的持续时间,因而使用的是新的默认时间:250毫秒。

再单击其他成员的照片时,应该隐藏之前显示的信息。要想跟踪当前显示的是哪一个成员的详细信息,只要使用一个active类即可,参见代码清单11-7。

代码清单11-7

  1. var $member = $(this);
  2. if ($member.hasClass('active')) {
  3. return;
  4. }
  5. $('div.member.active')
  6. .removeClass('active')
  7. .children('div').fadeOut();
  8. $member.addClass('active');

新增的代码放在了showDetails()函数前面,也就是在被单击的成员<div>中添加active类。通过找到这个类,很容易确定不可见的元素并将其以动画方式淡出。如果被单击的成员<div>有这个active类,那就直接返回,什么也不做了。

注意,调用的.fadeOut()方法也使用了前面定义的比较快的250毫秒持续时间。这个默认值对jQuery所有的预置效果都是有效的,就像它对前面那个.animate()方法起作用一样。