4.2 jQuery中的动画

4.2 jQuery中的动画

动画效果也是jQuery库吸引人的地方。通过jQuery的动画方法,能够轻松地为网页添加非常精彩的视觉效果,给用户一种全新的体验。

4.2.1 show()方法和hide()方法

1.show()方法和hide()方法

show()方法和hide()方法是 jQuery 中最基本的动画方法。在 HTML 文档里,为一个元素调用hide()方法,会将该元素的display样式改为“none”。例如,使用如下代码隐藏element元素。

[插图]

这段代码的功能与用css()方法设置display属性效果相同:

[插图]

当把元素隐藏后,可以使用show()方法将元素的display样式设置为先前的显示状态(“block”或“inline”或其他除了“none”之外的值)。

jQuery代码如下:

[插图]

在前面的例子中,已经多次使用hide()方法和show()方法,通过这两种方法可以控制“内容”的显示和隐藏。

jQuery代码如下:

[插图]

注意hide()方法在将“内容”的display属性值设置为“none”之前,会记住原先的display属性值(“block”或“inline”或其他除了“none”之外的值)。当调用show()方法时,就会根据hide()方法记住的display属性值来显示元素。

在本例中,“内容”的display 属性的值是“block”,当单击“标题”链接执行 hide()方法的时候,hide()方法会做两步动作,首先会记住“内容”的display属性的值“block”,然后把display属性的值设置为“none”。

在Firebug工具中DOM结构显示效果如图4-21所示。

[插图]

图4-21 执行hide()方法

当执行show()方法的时候,“内容”的display属性的值就会被还原为调用hide()方法前的状态。

在Firebug工具中DOM结构显示效果如图4-22所示。

[插图]

图4-22 执行show()方法
注意:用 jQuery做动画效果要求要在标准模式下,否则可能会引起动画抖动。标准模式即要求文件头部包含如下的DTD定义:``

2.show()方法和hide()方法让元素动起来

show()方法和hide()方法在不带任何参数的情况下,相当于css(“display”,”none/block/inline”),作用是立即隐藏或显示匹配的元素,不会有任何动画。如果希望在调用show()方法时,元素慢慢地显示出来,可以为show()方法指定一个速度参数,例如,指定一个速度关键字“slow”。jQuery代码如下:

[插图]

运行该代码后,元素将在600毫秒内慢慢地显示出来。其他的速度关键字还有“normal”和“fast”(长度分别是400毫秒和200毫秒)。

不仅如此,还可以为显示速度指定一个数字,单位是毫秒。

例如,使用如下代码使元素在1秒钟(1000毫秒)内显示出来:

[插图]

类似的,以下代码将使元素在1秒钟(1000毫秒)内隐藏:

[插图]

在前面的例子中,把其中的hide()方法改为hide(600),show()方法改为show(600)。jQuery代码如下:

[插图]

运行该代码后,当单击“标题”链接时,“内容”已经产生动画了。效果如图4-23所示。

[插图]

图4-23 hide(600)方法执行效果过程

从代码执行过程中,可以发现,hide(600)方法会同时减少“内容”的高度、宽度和不透明度,直至这3个属性的值都为0,最后设置该元素的CSS规则为“display:none”。同理,show(600)方法则会从上到下增大“内容”的高度,从左到右增大“内容”的宽度,同时增加“内容”的不透明度,直至新闻内容完全显示。

4.2.2 fadeIn()方法和fadeOut()方法

与show()方法不相同的是,fadeIn()方法和fadeOut()方法只改变元素的不透明度。fadeOut()方法会在指定的一段时间内降低元素的不透明度,直到元素完全消失(“display: none”)。fadeIn()方法则相反。

在上个例子中,如果只想改变“内容”的不透明度,就可以使用fadeOut()方法。

jQuery代码如下:

[插图]

当第1 次单击“标题”链接后,“内容”慢慢地消失了(淡出),当再次单击“标题”链接后,“内容”又慢慢地显示了(淡入),效果如图4-24所示。

[插图]

图4-24 段落元素淡化效果

4.2.3 slideUp()方法和slideDown()方法

slideUp()方法和slideDown()方法只会改变元素的高度。如果一个元素的display属性值为“none”,当调用 slideDown()方法时,这个元素将由上至下延伸显示。slideUp()方法正好相反,元素将由下到上缩短隐藏。使用 slideUp()方法和slideDown()方法再次对“内容”的显示和隐藏方式进行改变,代码如下:

[插图]

实现效果如图4-25所示。

[插图]

图4-25 “内容”正在向下展开显示
注意:jQuery中的任何动画效果,都可以指定3种速度参数,即“slow”、“normal”和“fast”(时间长度分别是0.6秒、0.4秒和0.2秒)。当使用速度关键字时要加引号,例如show("slow"),如果用数字作为时间参数时就不需要加引号,例如show(1000)。

4.2.4 自定义动画方法animate()

前面已经讲了3种类型的动画。其中show()方法和hide()方法会同时修改元素的多个样式属性,即高度、宽度和不透明度;fadeOut()方法和fadeIn()方法只会修改元素的不透明度;slideDown()方法和slideUp()方法只会改变元素的高度。

很多情况下,这些方法无法满足用户的各种需求,那么就需要对动画有更多的控制,需要采取一些高级的自定义动画来解决这些问题。在jQuery中,可以使用animate()方法来自定义动画。其语法结构为:

[插图]

参数说明如下。

(1)params:一个包含样式属性及值的映射,比如{property1:“value1”,property2: “value2”,…}。
(2)speed:速度参数,可选。
(3)callback:在动画完成时执行的函数,可选。

1.自定义简单动画

前面的几个例子,从不同的方面使元素动了起来,animate()方法也可以使元素动起来,而且animate()方法更具有灵活性。通过animate()方法,能够实现更加精致新颖的动画效果。

首先来看一个简单例子,有一个空白的HTML文档,里面有一个id=”panel”的<div>元素,当<div>元素被单击后,能在页面上横向飘动。

先给这个<div>元素添加CSS样式。

[插图]

此时页面的初始化效果如图4-26所示。

[插图]

图4-26 网页初始化效果

为了使这个元素动起来,要更改元素的“left”样式属性。需要注意的是在使用animate()方法之前,为了能影响该元素的“top”、“left”、“bottom”和“right”样式属性,必须先把元素的position样式设置为“relative”或者“absolute”。本例中,设置的是“position:relative”,有了这个值,就可以调整元素的left属性,使元素动起来。

现在,添加如下jQuery代码:

[插图]

在本段代码中,首先为id为“panel”的元素创建一个单击事件,然后对元素加入animate()方法,使元素在3秒(3000毫秒)内,向右移动500像素。运行效果如图4-27所示。

[插图]

图4-27 `
`元素右移500像素

2.累加、累减动画

在之前的代码中,设置了{left: “500px”}作为动画参数。如果在500px之前加上“+=”或者“- =”符号即表示在当前位置累加或者累减。代码如下:

[插图]

3.多重动画

(1)同时执行多个动画

在上面的例子中,通过控制属性left的值实现了动画的效果,这是一个很单一的动画。如果需要同时执行多个动画,例如在元素向右滑动的同时,放大元素的高度。根据animate()方法的语法结构,可以写出如下的jQuery代码:

[插图]

运行代码后,<div>元素在向右滑动的同时,也会放大高度。

(2)按顺序执行多个动画

上例中,两个动画效果(left:”500px”和height:”200px”)是同时发生的,如果想要按顺序执行动画,例如让<div>元素先向右滑动,然后再放大它的高度,只需把代码拆开,然后按照顺序写就可以了,jQuery代码如下:

[插图]

因为animate()方法都是对同一个jQuery对象进行操作,所以也可以改为链式的写法,代码如下:

[插图]

这样一来,就满足上文提出的需求了。在“left”这个定位属性改变之前,“height”属性将不会被改变。像这样,动画效果的执行具有先后顺序,称为“动画队列”。

4.综合动画

接下来将完成更复杂的动画。单击<div>元素后让它向右移动的同时增大它的高度,并将它的不透明度从50%变换到100%,然后再让它从上到下移动,同时它的宽度变大,当完成这些效果后,让它以淡出的方式隐藏。

实现这些功能的jQuery代码如下:

[插图]

运行代码后,动画效果一步步执行完毕。通过这个例子可以看出,为同一元素应用多重效果时,可以通过链式方式对这些效果进行排队。

4.2.5 动画回调函数

在上例中,如果想在最后一步切换元素的CSS样式,而不是隐藏元素:

[插图]

如果只是按照常规的方式,将fadeOut (“slow”) 改为css (“border”,”5px solidblue”)

这样并不能得到预期效果。预期的效果是在动画的最后一步改变元素的样式,而实际的效果是,刚开始执行动画的时候,css()方法就被执行了。

出现这个问题的原因是 css()方法并不会加入到动画队列中,而是立即执行。可以使用回调函数(callback)对非动画方法实现排队。只要把 css()方法写在最后一个动画的回调函数里即可。代码如下:

[插图]

这样一来,css()方法就加入到动画队列中了,从而满足了上文提出的需求。

注意:callback回调函数适用于jQuery所有的动画效果方法,例如slideDown()方法的回调函数:

[插图]

这段代码表示id = “element”的元素将在0.4秒内(正常速度)向下完全展开。当动画完成后,执行回调函数体内的代码。

4.2.6 停止动画和判断是否处于动画状态

1.停止元素的动画

很多时候需要停止匹配元素正在进行的动画,例如上例的动画,如果需要在某处停止动画,需要使用stop()方法。stop()方法的语法结构为:

[插图]

参数clearQueue和gotoEnd都是可选的参数,为Boolean值(ture或flase)。clearQueue代表是否要清空未执行完的动画队列,gotoEnd代表是否直接将正在执行的动画跳转到末状态。

如果直接使用stop()方法,则会立即停止当前正在进行的动画,如果接下来还有动画等待继续进行,则以当前状态开始接下来的动画。经常会遇到这种情况,在为一个元素绑定hover事件之后,用户把光标移入元素时会触发动画效果,而当这个动画还没结束时,用户就将光标移出这个元素了,那么光标移出的动画效果将会被放进队列之中,等待光标移入的动画结束后再执行。因此如果光标移入移出得过快就会导致动画效果与光标的动作不一致。此时只要在光标的移入、移出动画之前加入stop()方法,就能解决这个问题。stop()方法会结束当前正在进行的动画,并立即执行队列中的下一个动画。以下代码就可以解决刚才的问题。

[插图]

如果遇到组合动画,例如:

[插图]

此时只用一个不带参数的stop()方法就显得力不从心了。因为stop()方法只会停止正在进行的动画,如果动画正执行在第1阶段(改变height的阶段),则触发光标移出事件后,只会停止当前的动画,并继续进行下面的animate({width : “300” } ,300) 动画,而光标移出事件中的动画要等这个动画结束后才会继续执行,这显然不是预期的结果。这种情况下stop()方法的第1个参数就发挥作用了,可以把第1个参数(clearQueue)设置为true,此时程序会把当前元素接下来尚未执行完的动画队列都清空。把上面的代码改成如下代码,就能实现预期的效果。

[插图]

第2个参数(gotoEnd)可以用于让正在执行的动画直接到达结束时刻的状态,通常用于后一个动画需要基于前一个动画的末状态的情况,可以通过stop(false,true)这种方式来让当前动画直接到达末状态。

当然也可以两者结合起来使用 stop(true,true),即停止当前动画并直接到达当前动画的末状态,并清空动画队列。

注意,jQuery只能设置正在执行的动画的最终状态,而没有提供直接到达未执行动画队列最终状态的方法。例如有一组动画:

[插图]

无论怎么设置stop()方法,均无法在改变“width”或者“height”时,将此<div>元素的末状态变成300 × 150的大小,并且设置透明度为0.2。

2.判断元素是否处于动画状态

在使用animate()方法的时候,要避免动画积累而导致的动画与用户的行为不一致。当用户快速在某个元素上执行 animate()动画时,就会出现动画积累。解决方法是判断元素是否正处于动画状态,如果元素不处于动画状态,才为元素添加新的动画,否则不添加。代码如下:

[插图]

这个判断方法在animate()动画中经常被用到,需要特别注意。

3.延迟动画

在动画执行的过程中,如果想对动画进行延迟操作,那么可以使用delay()方法,使用方式如下:

[插图]

delay()方法允许我们将队列中的函数延时执行。它既可以推迟动画队列中函数的执行,也可以用于自定义队列。

4.2.7 其他动画方法

除了上面提到的动画方法,jQuery中还有4个专门用于交互的动画方法。

  • toggle( speed, [callback] )
  • slideToggle( speed, [ easing ], [callback] )
  • fadeTo( speed, opacity, [callback] )
  • fadeToggle ( speed, [ easing ], [callback] )

1.toggle()方法

toggle()方法可以切换元素的可见状态。如果元素是可见的,则切换为隐藏的;如果元素是隐藏的,则切换为可见的。

给“内容”添加toggle()事件,代码如下:

[插图]

当单击“标题”链接后,“内容”会在可见和隐藏两种状态之间切换。

相当于以下jQuery代码:

[插图]

2.slideToggle()方法

slideToggle()方法通过高度变化来切换匹配元素的可见性。这个动画效果只调整元素的高度。

给“内容”添加slideToggle()事件,代码如下:

[插图]

当单击“标题”链接后,“内容”会在可见和隐藏两种状态之间切换,不过是通过改变元素的高度来实现的。

相当于以下jQuery代码:

[插图]

3.fadeTo()方法

fadeTo()方法可以把元素的不透明度以渐进方式调整到指定的值。这个动画只调整元素的不透明度,即匹配的元素的高度和宽度不会发生变化。

给“内容”添加fadeTo()事件,代码如下:

[插图]

当“标题”链接被单击后,“内容”会渐渐地调整到指定的不透明度(20%)。

4.fadeToggle()方法

fadeToggle()方法通过不透明度变化来切换匹配元素的可见性。这个动画效果只调整元素的不透明度。

给“内容”添加fadeToggle()事件,代码如下:

[插图]

相当于以下jQuery代码:

[插图]

4.2.8 动画方法概括

从基本动画方法hide()和show()到fadeIn()和fadeOut(),然后到slideUp()和slideDown(),再到自定义动画方法animate(),最后到交互动画方法toggle()、slideToggle(),fadeTo()和fadeToggle()。在介绍了如此多的动画方法后,现总结概括如下。

1.改变样式属性

表4-1 动画方法说明

[插图]

需要特别注意animate()方法,可以使用它来替代其他所有的动画方法。

  • 用animate()方法代替show()方法:

[插图]

等价于:

[插图]

  • 用animate()方法代替fadeIn()方法:

[插图]

等价于:

[插图]

  • 用animate()方法代替slideDown()方法:

[插图]

等价于:

[插图]

  • 用animate()方法代替fadeTo()方法:

[插图]

等价于:

[插图]

事实上,这些动画就是 animate()方法的一种内置了特定样式属性的简写形式。在animate()方法中,这些特定样式的属性值可以为“show”、“hide”和“toggle”,也可以是自定义数字(值)。

2.动画队列

(1)一组元素上的动画效果

  • 当在一个animate()方法中应用多个属性时,动画是同时发生的。
  • 当以链式的写法应用动画方法时,动画是按照顺序发生的。

(2)多组元素上的动画效果

  • 默认情况下,动画都是同时发生的。
  • 当以回调的形式应用动画方式时,动画是按照回调顺序发生的。

另外,在动画方法中,要注意其他非动画方法会插队,例如 css()方法要使非动画方法也按照顺序执行,需要把这些方法写在动画方法的回调函数中。