第4章 jQuery的事件和动画(二)

时间:2023-03-09 04:10:53
第4章 jQuery的事件和动画(二)

二. jQuery中的动画

动画在前面几章案例中是回避不了的问题。此处结合一些简便的写法稍作系统的分析。

1. show()和hide()
(1)介绍——不用过多的介绍了
jQuery最基本的方法。本质是某个html对象的display从none和显示之间切换的丰富过程。在display为none之前,jq会记住原来对象的显示方式。原来是inline,再次调用show()方法时,显示方式不变。

回到例4.1中FAQ的例子——(运行环境jQuery1.7.2

     $(document).ready(function(){
$('#panel h5.head').bind('click',function({
$('#panel h5.head').toggle(function(){
$(this).next().hide();
},function(){
$(this).next().show();
})
})
})
或者
     $(document).ready(function(){
var bShow=false;
$('#panel h5.head').bind('click',function({
if(bShow){
$(this).next().hide();
}else{
$(this).next().show()
}
bShow=!bShow;
})
})
 第4章 jQuery的事件和动画(二)

可以发现,该例子中的宽、高、不透明度都是变化的。display:none只是函数的终点。

2.fadeIn()和fadeOut()

只改变不透明度,相关元素的节点都存在。

jq1

     $(document).ready(function(){
$('#panel h5.head').click(function(){
$(this).next().fadeToggle();
})
})
注:fadeToggle通过不透明度的变化来开关所有匹配元素的淡入和淡出效果,这个动画只调整元素的不透明度,也就是说所有匹配的元素的高度和宽度不会发生变化。

jq2

     $(document).ready(function(){
$('#panel h5.head').bind('click',function(){
if($(this).next().is(':visible')){
$(this).next().fadeOut();
}else{
$(this).next().fadeIn();
}
})
})
 再对案例进行修改

第4章 jQuery的事件和动画(二)

【补白】可以使用fadeTo()方法来实现不透明度的渐进式变化——这相当于介乎fadeIn-fadeOut方法的一个中间状态。
     $(document).ready(function(){
$('#panel h5.head').click(function(){
$(this).next().fadeToggle(600,0.2);
})
})

3. slideDown()和slideUp()

slideDown()元素由上至下显示。slideUp()正好相反。以下两段代码都可以替代toggle()使用

注:slideToggle通过高度变化来切换所有匹配元素的可见性,这个动画效果只调整元素的高度,可以使匹配的元素以“滑动”的方式隐藏或显示。

jq1

     $(document).ready(function(){
$('#panel h5.head').click(function(){
$(this).next().slideToggle();
})
})
jq2
     $(document).ready(function(){
$('#panel h5.head').bind('click',function(){
if($(this).next().is(':visible')){
$(this).next().slideUp();
}else{
$(this).next().slideDown();
}
})
})

第4章 jQuery的事件和动画(二)

4.参数

以上三类函数都可以用一套参数。

不带任何参数时,显示方式是马上变化。
fast——200ms显示
normal——400ms显示
slow——600ms显示
也可以直接写数字,比如show(300)表示在300ms内显示完毕。

【小结】可以认为show-hide方法是fadeIn-fadeOut(改变透明度)和slideUp-slideDown(改变高度)的综合。它既改变又改变透明度。

5.自定义动画方法——animate()

     animate(params,speed,callback)
params包含样式属性和值的映射。注意,和css不同的是这里用逗号隔开,而不是分号!比如
  { 样式1:值1, 样式2:值2,... } 
speed:速度参数(可选)
callback:动画完成时执行的函数(可选)

(1)自定义一个简单的动画吧

【例4.2】一个空白文档, 一个div被单击后能在页面横向飘动。

     <divid="div1"></div>

     *{margin:0;padding:0}
#div1{
width:100px;height:100px;
background: red;
position: absolute;
margin:20px;
}
jq
     $(function(){
$('#div1').click(function(){
alert($(this).attr('left'))
$(this).animate({left:500+'px'},3000);//3s内移动到左距离500px处
});
});
速度由慢到快再减为0.

第4章 jQuery的事件和动画(二)

(2)累加累减

上面的案例套用原生js分析,运动就是#div1的offsetLeft不断增加的过程。代码{left:500+'px'}提示了运动的终点是500px处,但当定位不同时,运动的距离不一样。有时候我们不知道自己身在何处,只知道最终前进的方向和距离。这时适用于累加累减动画

     $(function(){
$('#div1').click(function(){
$(this).animate({left:'+=500px'},3000);//3s内向右移动500px
});
});

(3)再复杂一点点

要求:div1向右运动同时,增加宽度。
     $(function(){
$('#div1').click(function(){
$(this).animate({left:'+=500px',width:'200px'},3000);//3s内向右移动500px
});
});
 第4章 jQuery的事件和动画(二)

(4)还不够

要求:div1运动完了之后,触发第二个运动:向右变窄——让变窄和运动同时发生吧
     $(function(){
$('#div1').click(function(){
$(this).animate({left:'500px',width:'200px'},3000);//第一个动画
$(this).animate({left:'600px',width:'100px'},1000);//接下来发生的动画
}
);
});
结果真的可以,但是录屏软件诡异地无法记录这一过程。所以只好自己试试了。

(5)综合运用

单击div1,向有运动变宽同时不透明度有0.5变为1,之后向下运动,最后淡出隐藏
     $(function(){
$('#div1').click(function(){
$(this).animate({left:'500px',width:'200px',opacity:'1'},3000)
.animate({left:'600px',width:'100px'},1000)
.animate({top:'500px',height:'200px'},3000)
.animate({top:'600px',height:'100px'},1000)
.fadeOut(600);
});
});
这个过程称为动画队列。

6.动画回调函数

如果上面例子最后一步我想让div1的颜色变为绿色,会遇到一个问题。如果把$(this).css('background','green')写进队列最后一行,不能取得预期效果。实际情况是变色与动画同时执行。
原因在于css改变属于非动画,直接排到队列里是不起作用的。如果要做,因使用回调函数,写在最后一个动画里边。
     $(function(){
$('#div1').click(function(){
$(this).animate({left:'500px',width:'200px',opacity:'1'},3000)
.animate({left:'600px',width:'100px'},1000)
.animate({top:'500px',height:'200px'},3000)
.animate({top:'600px',height:'100px'},1000,function(){
$(this).css('background','green')//回调函数
})
});
});

7.动画控制

(1)停止动画——stop()方法
     xxx.stop([clearQueue],[gotoEnd]);
两个参数都是布尔值,都是可选的。前者表示是否清空队列,后者则表示是否直接定格到最终画面。什么参数都不写——则中止当前步骤,跳到下一步骤继续执行。
场景1:设想一下,一个鼠标移入动画,还没展示完,用户就移出了。就需要stop()方法。
     $(function(){
$('#div1').hover(function(){
$(this).stop()
.animate(鼠标移入动画)
},function(){
$(this).stop()
.animate(鼠标移出动画)
})
});
而对于组合动画,需要使用带清除队列参数的stop方法。也就是stop(true)。其它和上面代码基本一致。
场景2:动画本是连续的。但是stop()突然把一步停了,接下来的执行其实也失去了意义。
解决方案:跳到最终状态。
stop(false,true)
gotoEnd参数通常和clearQueue参数这样组合起来用。

(2)动画判断

动画的一个重要原则在于:始终与用户行为一致。不然体验就会出现问题。

又一个简单的场景是:疯狂移入移出导致动画不断叠加,"久久不能平息"。

因此,需要加一个判断模块:

a.当前动画如果已经结束,则可以执行用户触发的又一个动画;

b.当前如果未结束,那就不执行任何动画!

     if(!对象.is(':animated')){
//如果当前没有进行动画,则在此执行新动画
}else{...}
(3)延迟动画——delay()方法
比如说,我想让某个动画过1s后再执行。
     xxx.animate({属性1:'值1',...},动画执行时间).delay(1000)
8.动画方法小结
(1)本节介绍的动画效果,贯穿各种分析,会发现,这些效果全部是可以通过animate来实现的。透明度——渐进式宽高变化——位置变化,无非就是这三样东西而已。
(2)动画队列的发生顺序:
a.一个animate多个属性变化————同时发生
b.正常情况下链式写法:动画是按顺序发生的
c.多组元素下的动画————默认同时发生
d.回调函数把非动画(比如css改变)插入到动画队列——按顺序发生
【久违的大案例】图片滚动

第4章 jQuery的事件和动画(二)

难点:

(1)首尾如何跳转

(2)注意蓝色的圆点切换

布局

     <divid="cartoon">
<divclass="header">
<h4>卡通动漫</h4>
<ulclass="dot">
<li></li>
<li></li>
<li></li>
<li></li>
</ul>
<divclass="btn">
<divclass="btn1"></div>
<divclass="btn2"></div>
</div>
<divclass="more"><ahref="javascript:;">更多</a></div>
</div>
<ulclass="scroll">
<li>
<imgsrc="data:images/01.jpg"/>
<div>
<h6><ahref="javascript:;">海贼王</a></h6>
<p>播放次数:888</p>
</div>
</li>
<li>
<imgsrc="data:images/01.jpg"/>
<div>
<h6><ahref="javascript:;">海贼王</a></h6>
<p>播放次数:888</p>
</div>
</li><li>
<imgsrc="data:images/01.jpg"/>
<div>
<h6><ahref="javascript:;">海贼王</a></h6>
<p>播放次数:888</p>
</div>
</li><li>
<imgsrc="data:images/01.jpg"/>
<div>
<h6><ahref="javascript:;">海贼王</a></h6>
<p>播放次数:888</p>
</div>
</li>
<li>
<imgsrc="data:images/02.jpg"/>
<div>
<h6><ahref="javascript:;">叮当</a></h6>
<p>播放次数:889</p>
</div>
</li>
<li>
<imgsrc="data:images/02.jpg"/>
<div>
<h6><ahref="javascript:;">叮当</a></h6>
<p>播放次数:889</p>
</div>
</li>
<li>
<imgsrc="data:images/02.jpg"/>
<div>
<h6><ahref="javascript:;">叮当</a></h6>
<p>播放次数:889</p>
</div>
</li>
<li>
<imgsrc="data:images/02.jpg"/>
<div>
<h6><ahref="javascript:;">叮当</a></h6>
<p>播放次数:889</p>
</div>
</li>
<li>
<imgsrc="data:images/03.jpg"/>
<div>
<h6><ahref="javascript:;">火影</a></h6>
<p>播放次数:887</p>
</div>
</li>
<li>
<imgsrc="data:images/03.jpg"/>
<div>
<h6><ahref="javascript:;">火影</a></h6>
<p>播放次数:887</p>
</div>
</li>
<li>
<imgsrc="data:images/03.jpg"/>
<div>
<h6><ahref="javascript:;">火影</a></h6>
<p>播放次数:887</p>
</div>
</li>
<li>
<imgsrc="data:images/03.jpg"/>
<div>
<h6><ahref="javascript:;">火影</a></h6>
<p>播放次数:887</p>
</div>
</li>
<li>
<imgsrc="data:images/04.jpg"/>
<div>
<h6><ahref="javascript:;">龙珠</a></h6>
<p>播放次数:886</p>
</div>
</li>
<li>
<imgsrc="data:images/04.jpg"/>
<div>
<h6><ahref="javascript:;">龙珠</a></h6>
<p>播放次数:886</p>
</div>
</li>
<li>
<imgsrc="data:images/04.jpg"/>
<div>
<h6><ahref="javascript:;">龙珠</a></h6>
<p>播放次数:886</p>
</div>
</li>
<li>
<imgsrc="data:images/04.jpg"/>
<div>
<h6><ahref="javascript:;">龙珠</a></h6>
<p>播放次数:886</p>
</div>
</li>
</ul>
</div>

css

     *{
margin:;padding:;
font-family:"微软雅黑",arial;
}
ul li{
list-style:none;
}
a{
text-decoration: none;
}
#cartoon{
width:596px;height:186px;
border:1px solid #ccc;
border-radius:4px4px00;
margin:100pxauto;
position: relative;
overflow: hidden;
}
.header{
height:30px;
background: linear-gradient(#f2f2f2,#e3e3e3);
}
h4{
width:70px;float: left;
height:30px;line-height:30px;
margin-left:12px;
}
.dot{
padding:10px;width:60px;
float: left;
}
.dot>li{
width:8px;height:8px;
border-radius:50%;
background:#04AEF4;
float: left;margin-right:4px;
}
.btn,.more{
float: left;
}
.btn{
width:57px;height:20px;
border-radius:2px;
box-shadow:1px1px3px#999;
margin-top:5px;
cursor: pointer;
}
.btn1{
width:29px;height:20px;float: left;
background: url(../images/btn_cartoon_01.gif)
}
.btn2{
width:28px;height:20px;float: left;
background: url(../images/btn_cartoon_02.gif)
}
.more{
line-height:30px;margin-left:320px;
}
.more a{
line-height:30px;
font-style: italic;
color:#2B93D2;
}
#cartoon>ul{
height:158px;
position: absolute;
}
#cartoon>ul>li{
float: left;
padding:10px;
}
ul a{
font-size:12px;
color:#2B93D2;
line-height:24px;
}
ul a:hover{
text-decoration: underline;
color:#E31E1C;
}
ul p{
font-size:12px;
color:#666;
line-height:18px;
}
jq
思路是用一个计数器控制运动轨迹和小圆点变化
     $(function(){
var count=0;
var aDotLi=document.getElementsByClassName('dot')[0].getElementsByTagName('li');
//获取原点li
aDotLi[0].style.background='#04AEF4';
$('.scroll').css('width',(($('.scroll>li').width()+20)*$('.scroll>li').length)+'px');
//设置滚动ul的宽度。(设不设置都好像可以。)
//
$('#btn1').click(function(){
if($('.scroll').is(':animated')==true){
returnfalse;
}//控制动画模块
$('.dot>li').css('background','#fff');//初始化原点颜色
count-=1;
if(count<0){
count=count+4;
}//原点计算规则:0/3/2/1/0/3/2/1......
$('.scroll').animate({left:-148*4*(count)+'px'},300);
aDotLi[count].style.background='#04AEF4';
})
$('#btn2').click(function(){
if($('.scroll').is(':animated')==true){
returnfalse;
}
$('.dot>li').css('background','#fff');
count+=1;
if(count>3){
count=0;
}//计算规则:0/1/2/3/0/1/2/3...
$('.scroll').animate({left:-148*4*count+'px'},300);
aDotLi[count].style.background='#04AEF4';
})
})