写在前面
参考文献:莫振杰《从0到1:jQuery快速上手》
这期讲点别的——动画。
JQ动画
emm,动画,这个会不会有点难?
其实不算吧,我看完下来,感觉还是很OK的。
CSS3其实也可以实现动画,只不过JQ动画更方便控制。
比如说,JQ动画能够控制动画的执行、结合DOM操作、动画执行后会返回一个函数。
是的,没有看错,是一个函数。
动画有很多种,这期讲的都是简单的。
显示与隐藏
在JQ中,显示与隐藏有两种方法。
show()和hide()
toggle()
你可以这么理解——toggle就是show()和hide()的合成方法。、
show()和hide()
语法:
$().show(speed, fn)
$().hide(speed, fn)
show()方法会把元素由原来的display: none改为原来的状态(比如说行内块、块元素等)。
hide()方法会把元素改为display: none。
speed:可选参数,表示动画的速度,单位是毫秒(一秒等于一千毫秒),在这里我们不需要写单位,直接写数值或者字符串即可;在后面我们会常看到这个参数,下面不重复说了。
如果我们省略speed,表示没有动画效果,直接切换状态。
speed有两种取值,一个是字符串,一种是数值。
fast | 200 |
normal | 400(默认) |
slow | 600 |
fn是一个可选参数,表示动画执行完之后的回调函数。
回调函数,指的是动画执行完之后的再执行的函数。
一般来说,简单效果我们通常不写回调函数。
toggle()
toggle中文就是切换的意思,我们可以通过中英文意思来判断一个方法/函数的作用——所以我们在定义函数的时候,就应该遵循这个规则。
toggle()方法:如果元素是显示状态的,就切换到隐藏;反之,则切换到显示。
语法:$().toggle(speed, fn)
speed、fn同上,不说。
注意:toggle()方法在JQ 3.x版本已经移除了,所以说,不建议使用这个。
不过,我不是很理解为什么要移除这个方法。
淡入和淡出
实现元素的淡入淡出效果,有以下三种方法:
fadeIn()和fadeOut()
fadeToggle()
fadeTo()
前面两个跟show()和hide()方法与toggle()方法的关系是一致的。
fadeIn()和fadeOut()
语法:
$().fadeIn(speed, fn)
$().fadeOut(speed, fn)
其中in是淡入的意思,out是淡出的意思。
参数解析看show()和hide()方法。
在实际效果中,fadeIn()和fadeOut()方法实现的淡入和淡出效果和使用show()和hide()方法实现的带动画的显示与隐藏几乎是一模一样的,那这两个能不能互相替代?
不能。
show()和hide()是通过改变height、width、opacity、display等属性来实现元素的显示与隐藏。
fadeIn()和fadeOut()是通过改变opacity、display等属性来实现元素的淡入和淡出。
在底层逻辑支持上,两者就不一样,而且视觉上的区别也不小,建议手动尝试一下。
fadeToggle()
fadeToggle()方法可以理解为fadeIn()和fadeOut()方法的合成方法。
语法:$().fadeToggle(speed, fn)
参数同上一致,不展开。
上面都是效果类似的,下面说个特殊效果的淡入淡出。
fadeTo()
在淡入效果中,透明度(opacity属性)是从0-1开始变化的;在淡出效果中,透明度(opacity属性)是从1-0开始变化的。
如果我想要指定变化到0-1之间的某个值,要怎么做?
语法:$().fadeTo(speed, opacity, fn)
其他参数同上,opacity表示透明度,通常都是0-1之间的数值,取值范围0.0-1.0。
这个效果适合做选中,或者是实现hover变灰的效果。
注意:fadeTo()方法只会把元素的透明度指定到某个值,并不会隐藏元素。
滑上与滑下
这个效果第一眼看的时候,很蒙圈;第二眼看到的时候,还是很蒙圈。
但其实这个效果很常见,比如说导航栏的下拉框,就经常使用这个效果。
实现元素的滑动效果,有以下两个方式:
slideUP()和slideDown()
slideToggle()
slideUp()和slideDown()
语法:
$().slideUp(speed, fn)
$().slideDown(speed, fn)
slideToggle()
$().slideToggle(speed, fn)
上面全是预设动画,下面说点高级一点的。
自定义动画
自定义又分为三种:
简单动画
累积动画
回调动画
在JQ中,对于自定义动画,都是使用animate()方法实现的。
简单动画
语法:$().animate(params, speed, fn)
params是必选参数,表示属性值列表——也就是元素在动画执行过程中变化的属性列表。
其他两个参数同上。
params采用“键值对”的形式:
{ "属性1": "属性值1", "属性2": "属性值2", ... , "属性n": "属性值n" }。
注意,宽和高可以不写单位。
bug:
$().animate({"width": "400", "height": "500", "background-color": "red"}, 800),可以发现颜色不会发生改变。
解决:
引入插件——jQuery.color.js即可解决此问题。
注意引入位置,引入位置要在引入JQ之后。
累积动画
在JQ中,对于元素的宽高,可以使用+/-=这两个运算符来实现累积动画的效果。
语法:$().animate(params, speed, fn)
params里面还是使用键值对的方式,但是width和height的值可以是"+/-=数值px"。
其他参数同上。
回调函数
之前一直没说回调函数,现在仔细讲讲。
元素的动画执行完成之后,我们可以在回调函数里面再添加一些别的效果。
比如说,执行完成之后,给选定的元素修改背景色,或者增加边框等。
而如果我们直接使用$().animate().css()方法实现,可以发现,css内的样式是直接就生效的。
这是为什么?
因为css()方法并不会加入到“动画队列”当中,而是立即执行了。
而如果我们把css()方法放到animate中的fn()函数中,就可以实现这个效果了。
队列动画
上文说过,动画队列,这次就盘它。
如果我们想实现先改变某个样式属性之后,再改变另外一个样式属性,想要产生前后分离的效果,该怎么实现?
语法:$().animate().animate(). ... .animate()
动画队列,其实就是按照animate()方法调用的先后顺序来实现的。
上面的css()其实也可以装进到新的animate()方法中,只需要把其中的样式插入到params里面即可。
队列动画的形式:
显示与隐藏
淡入与淡出
滑上与滑下
自定义动画
停止动画
如果我想停止某一段动画时该怎么办?
比如说,hover某些元素时动画执行,当移出鼠标之后,就停止这个动画。
在JQ中,我们可以使用stop()方法来停止元素正在执行的动画效果。
语法:$().stop(stopAll, goToEnd)
stopAll和goToEnd都是可选参数,它们的取值都是布尔值,默认都是false。
stopAll表示停止队列动画,当取值为false的时候,仅停止当前执行的动画;当取值为true的时候,停止当前动画,以及后面所有的队列动画。
goToEnd表示将动画跳转到当前动画效果的最终状态。
这两个参数,两两组合,有四种结果:
stop() | 两个取值都是false,仅停止当前动画,后面的动画继续执行 |
stop(true) | 停止当前动画,并且后面的动画也停止执行 |
stop(true, true) | 当前动画继续执行,只停止后面的动画 |
stop(false, true) | 停止当前动画,跳到最后一个动画,并且执行最后一个动画 |
bug:
如果我们使用hover来实现动画效果,因为hover内有两个fn参数,当我们在不断地移入移出元素时,可以发现元素会不断地变长变短——动画会不断执行,并不会停止。
bug产生的原因:在JQ中,如果一个动画没有执行完,它就会被添加到“动画队列”中去。
解决:先stop(),然后再使用animate()即可。
补充:这个bug,好像在哪里见过?定时器?
延迟动画
延迟就是delay,delay就是延迟。
在JQ中,我们使用delay()方法来延迟执行动画。
语法:$().delay(speed)
注意:speed是必选参数,表示动画的速度,单位为毫秒。
毫秒怎么跟秒换算?
判断动画状态
上面说到的bug,除了先调用stop()方法以外,我们还可以使用判断动画状态来解决。
语法:$().is(":animated")
在hover的fn函数内部直接使用if来判断当前元素在执行动画,如果不是则添加新的动画。
注意:这里的:animated是一个伪类选择器,表示选取所有的正在执行动画的元素。
这个方法比stop()方法更常用。
深入了解JQ动画
在上文,我们一共学了4种动画形式:
显示与隐藏
淡入与淡出
滑上与滑下
自定义动画
那么有人想过它的原理是什么吗?
其实,JQ动画本质上都是通过改变元素的CSS属性来实现的。
鉴于最后一种方法其实很赤果果,所以我们不说。
详细说说前三种吧。
显示与隐藏:通过改变display、opacity、width、height来实现。
淡入与淡出:通过改变display、opacity来实现。
滑上与滑下:通过改变display、height来实现。
实际上,这三个方法都可以使用自定义动画——animate()方法来实现。
换句话说,底层支持是animate()。
可以尝试一下,使用animate()方法来实现前三种方法吧。
写在最后
这次就说动画吧,下次说说其他方法。