有些复杂的动画通过之前学到的几个动画函数是不能够实现,这时候就是强大的 animate() 方法了。
为了满足实际开发中各种动画设计的需求,jQuery 为我们提供了一种“自定义动画”的解决方案。
对于自定义动画,我们分为以下 3 个方面来介绍:
在 jQuery 中,对于自定义动画,我们都是使用 animate() 方法来实现的。
语法:
params 是一个必选参数,表示属性值列表,也就是元素在动画中变化的属性列表。speed 是一个可选参数,表示动画的速度,单位为毫秒,默认为 400 毫秒。如果省略参数,则表示采用默认速度。fn也是一个可选参数,表示动画执行完成后的回调函数。
举例:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<style type="text/css">
div
{
width:50px;
height:50px;
background-color:lightskyblue;
}
</style>
<script src="js/jquery-1.12.4.min.js"></script>
<script>
$(function () {
$("div").click(function () {
$(this).animate({ "width": "150px", "height": "150px" }, 1000);
})
})
</script>
</head>
<body>
<div></div>
</body>
</html>
默认情况下,预览效果如图 1 所示。
我们点击 div 元素后,预览效果如图 2 所示。
从上面例子可以看出,animate() 方法的参数 params 采用的是“键值对”形式,语法如下。
在上面例子的基础上,如果还想同时使得背景颜色变为红色,我们很自然地写下了如下代码:
$("div").click(function () {
$(this).animate({ "width": "150px", "height": "150px" , "background-color": "red" }, 1000);
})
当我们测试时,背景颜色居然没有改变?!再检查一遍代码,也没发现有什么错误啊!这究竟是怎么回事呢?其实你没错,是 jQuery 错了!什么?jQuery 自己都有错?你逗我?
实际上,jQuery 本身有一个缺陷,就是使用 animate() 方法时会无法识别 background-color、border-color 等颜色属性。因此,我们需要引入第三方插件 jquery.color.js 来修复这个 bug。对于 jquery.color.js,小伙伴们可以自己去官网下载。
举例:引入 jquery.color.js
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<style type="text/css">
div
{
width:50px;
height:50px;
background-color:lightskyblue;
}
</style>
<script src="js/jquery-1.12.4.min.js"></script>
<script src="js/jquery.color.js"></script>
<script>
$(function () {
$("div").click(function () {
$(this).animate({ "width": "150px", "height": "150px" , "background-color": "red" }, 1000);
})
})
</script>
</head>
<body>
<div></div>
</body>
</html>
默认情况下,预览效果如图 3 所示。
我们点击 div 元素后,此时预览效果如图 4 所示。
这里大家要注意一点,由于 jquery.color.js 是依赖 jQuery 库存在的,因此 jquery.color.js 文件必须在 jquery 库文件后面引入,不然就无法生效。实际上,你可以把 jquery.color.js 看成是一个 jQuery 插件,这样更好理解。
在 jQuery 中,对于元素的宽度和高度,我们可以结合+=和-=这两个运算符来实现累积动画的效果。举个例子,{"width":"+=100px"} 表示以元素本身的 width 为基点加上 100px,而 {"width":"-=100px"} 表示以元素本身的 width 为基点减去 100px。
举例:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<style type="text/css">
div
{
width:50px;
height:50px;
background-color:lightskyblue;
}
</style>
<script src="js/jquery-1.12.4.min.js"></script>
<script>
$(function () {
//简单动画
$("#btn1").click(function () {
$("#box1").animate({ "width": "100px", "height": "100px" }, 1000);
})
//累积动画
$("#btn2").click(function () {
$("#box2").animate({ "width": "+=100px", "height": "+=100px" }, 1000);
})
})
</script>
</head>
<body>
<div id="box1"></div>
<input id="btn1" type="button" value="简单动画" /><br />
<div id="box2"></div>
<input id="btn2" type="button" value="累积动画" />
</body>
</html>
默认情况下,预览效果如图 5 所示。
我们点击两个按钮后,此时预览效果如图 6 所示。
animate({"width":"100px","height":"100px"},1000) 使用的是简单动画形式,因此元素最终的 width 为 100px,height 为 100px。animate({"width":"+=100px","height":"+=100px"},1000) 使用的是累积动画形式,因此元素最终的 width 为 150px,height 为 150px。
从这个例子我们可以看出,简单动画形式只是给定了元素属性的最终值,而累积动画形式是在元素原来值的基础上增加或减少。此外在这个例子中,我们多次点击【累积动画】按钮后,会发现这个动画效果会不断累积,小伙伴们可以自行测试。
在介绍回调函数之前,我们先来看这样一个效果:元素的动画执行完成后,再用 css() 方法为元素添加一个边框。
举例:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<style type="text/css">
div
{
width:50px;
height:50px;
background-color:lightskyblue;
}
</style>
<script src="js/jquery-1.12.4.min.js"></script>
<script>
$(function () {
$("div").click(function () {
$(this).animate({ "width": "150px", "height": "150px" }, 1000).css("border", "1px solid red");
})
})
</script>
</head>
<body>
<div></div>
</body>
</html>
默认情况下,预览效果如图 7 所示。
当我们点击 div 元素后,预览效果如图 8 所示。
我们可以发现,点击的一瞬间,元素就已经被添加了边框。也就是说,animate() 方法才刚刚执行,css() 方法也一起被执行了。这个与我们预期的效果完全不一样。因为我们想要的效果是 animate() 方法执行完成后,才去执行 css() 方法。
出现这种情况的根本原因在于 css() 方法并不会加入“动画队列”中,而是立即被执行了。在 jQuery 中,如果想要在动画执行完成后再执行某些操作,我们就需要用到 animate() 方法中的回调函数。
举例:回调函数
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<style type="text/css">
div
{
width:50px;
height:50px;
background-color:lightskyblue;
}
</style>
<script src="js/jquery-1.12.4.min.js"></script>
<script>
$(function () {
$("div").click(function () {
$(this).animate({ "width": "150px", "height": "150px" }, 1000, function(){
$(this).css("border", "2px solid red");
});
})
})
</script>
</head>
<body>
<div></div>
</body>
</html>
默认情况下,预览效果如图 9 所示。
我们点击 div 元素后,此时预览效果如图 10 所示。
使用回调函数,可以使得在动画执行完成之后,再执行某些操作。并不是只有 animate() 方法才有回调函数,实际上所有 jQuery 动画的方法都有回调函数,之前小伙伴们也接触过不少了。不过,回调函数在 jQuery 动画中用得不多,大家了解一下即可。
$("div").click(function(){
$(this).animate({"width":"100px",height:"100px"});
})
在上面这段代码实现的动画中,元素的 width 和 height 是同时改变的。如果我们想要“先”改变宽度,“后”改变高度,上面这段代码就没办法实现了,而需要借助队列动画才可以实现。
在 jQuery 中,队列动画指的是元素按照一定的顺序来执行多个动画效果。
语法:
队列动画,其实就是按照 animate() 方法调用的先后顺序来实现的,原理非常简单。
举例:队列动画
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<style type="text/css">
div
{
width:50px;
height:50px;
background-color:lightskyblue;
}
</style>
<script src="js/jquery-1.12.4.min.js"></script>
<script>
$(function () {
$("div").click(function () {
$(this).animate({ "width": "150px"}, 1000).animate({ "height": "150px" }, 1000);
})
})
</script>
</head>
<body>
<div></div>
</body>
</html>
默认情况下,预览效果如图 11 所示。
我们点击 div 元素后,div 元素会经历 2 个阶段的动画:首先宽度在 1 秒钟内由 50px 变成 150px,此时效果如图 12(a)所示;然后高度在 1 秒钟内由 50px 变成 150px,此时效果如图 12(b)所示。
在这个例子中,元素会先改变宽度,然后改变高度。也就是执行完第一个 animate() 方法后,才会去执行第二个 animate() 方法。
举例:复杂的队列动画
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<style type="text/css">
div
{
width:50px;
height:50px;
background-color:lightskyblue;
}
</style>
<script src="js/jquery-1.12.4.min.js"></script>
<script>
$(function () {
$("div").click(function () {
$(this).animate({ "width": "150px", "height": "150px"}, 1000).fadeOut(1000).fadeIn(1000);
})
})
</script>
</head>
<body>
<div></div>
</body>
</html>
默认情况下,浏览器效果如图 13 所示。
我们点击 div 元素后,div 元素会经历 3 个阶段的动画:首先改变宽度和高度,接着淡出消失,再接着淡入出现。最终效果如图 14 所示。
这里实现了一个比较复杂的队列动画效果:第 1 个动画是用 animate() 方法改变元素的宽和高,第 2 个动画是用 fadeOut() 方法实现元素的淡出效果,第 3 个动画是用 fadeIn() 方法实现元素的淡入效果。
可能小伙伴会问:“队列动画不是按 animate() 方法的先后顺序执行的吗?为什么像 fadeOut()、fadeIn() 方法也能加入到动画队列中呢?”这是因为 fadeOut()、fadeIn() 方法也属于动画,本质上也是使用 animate() 来实现的。
在 jQuery 中,队列动画可以是任何动画形式,包括显示与隐藏、淡入与淡出,滑上与滑下、自定义动画 4 种。