jQuery运动
$('#div1').hide(1000); //width height opacity
$('#div1').animate({ width : 'hide' , height : 'hide' , opacity : 'hide' },1000,'linear'});
//上面两条语句是等效的
$('#div1').slideToggle(1000); //height
$('#div1').animate({ height : 'toggle' },1000,'linear'});
//上面两条语句是等效的
源码分析
jQuery.each([ "toggle", "show", "hide" ], function( i, name ) {
var cssFn = jQuery.fn[ name ];
jQuery.fn[ name ] = function( speed, easing, callback ) {
return speed == null || typeof speed === "boolean" ?
cssFn.apply( this, arguments ) :
this.animate( genFx( name, true ), speed, easing, callback );
};
});
当.show(), .hide(), .toggle()没有参数时,调用原来的方法;有参数时调用.animate()
关于genFx(name,true)函数返回的结果就是类似{ width : 'hide' , height : 'hide' , opacity : 'hide' }
function genFx( type, includeWidth ) {//如果第二个参数是true,则设置宽度和透明度
var which,
attrs = { height: type },
i = 0;
// if we include width, step value is 1 to do all cssExpand values,
// if we don't include width, step value is 2 to skip over Left and Right
includeWidth = includeWidth? 1 : 0;
for( ; i < 4 ; i += 2 - includeWidth ) {
which = cssExpand[ i ];
attrs[ "margin" + which ] = attrs[ "padding" + which ] = type;
}
if ( includeWidth ) {
attrs.opacity = attrs.width = type;
}
return attrs;
}
其中cssExpand = [ "Top", "Right", "Bottom", "Left" ]
运动都是调用.animate()方法
jQuery.each({
slideDown: genFx("show"),
slideUp: genFx("hide"),
slideToggle: genFx("toggle"),
fadeIn: { opacity: "show" },
fadeOut: { opacity: "hide" },
fadeToggle: { opacity: "toggle" }
}, function( name, props ) {
jQuery.fn[ name ] = function( speed, easing, callback ) {
return this.animate( props, speed, easing, callback );
};
});
.fadeTo(1000,0.5)和.animate({ opacity : 0.5 },1000,'linear')的区别在于:
.fadeTo(1000,0.5)能够使隐藏的元素显示出来,透明度变成0.5,即先将元素透明度变成0,再显示,透明度在过渡到0.5
animate( { opacity : 0.5 },1000,'linear' )只是将透明度变成0.5,没有改变display属性,不能将隐藏的元素显示出来
.fadeTo():
animate( { opacity : 0.5 },1000,'linear' )只是将透明度变成0.5,没有改变display属性,不能将隐藏的元素显示出来
.fadeTo():
fadeTo: function( speed, to, easing, callback ) {
// show any hidden elements after setting opacity to 0
return this.filter( isHidden ).css( "opacity", 0 ).show()
// animate to the value specified
.end().animate({ opacity: to }, speed, easing, callback );
.animate()使用方法:
$('#div1').animate({ width : 400 },1000,'linear',function(){alert(111)});//该代码会转化成下面的代码
$('#div1').animate({ width : 400 },{
duration : '1000',
easing : 'linear',
complete : function(){
alert(111);
}
});
.animate()源码:
animate: function( prop, speed, easing, callback ) {
var empty = jQuery.isEmptyObject( prop ),
optall = jQuery.speed( speed, easing, callback ),//处理配置参数,将回调函数和出队函数合并成一个回调函数
doAnimation = function() {
// Operate on a copy of prop so per-property easing won't be lost
var anim = Animation( this, jQuery.extend( {}, prop ), optall );
// Empty animations, or finishing resolves immediately
if ( empty || data_priv.get( this, "finish" ) ) {
anim.stop( true );
}
};
doAnimation.finish = doAnimation;
return empty || optall.queue === false ?
this.each( doAnimation ) :
this.queue( optall.queue, doAnimation );//进行入队操作
},
处理配置参数源码:当jQuery.fx.off===true时,关闭所有运动,因为此时duration=0,
如果duration=‘slow’,则duration=600
jQuery.fx.speeds = {
slow: 600,
fast: 200,
// Default speed
_default: 400
};
slow: 600,
fast: 200,
// Default speed
_default: 400
};
jQuery.speed = function( speed, easing, fn ) {
var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : {
complete: fn || !fn && easing ||
jQuery.isFunction( speed ) && speed,
duration: speed,
easing: fn && easing || easing && !jQuery.isFunction( easing ) && easing
};
//
opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration :
opt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[ opt.duration ] : jQuery.fx.speeds._default;
// normalize opt.queue - true/undefined/null -> "fx"
if ( opt.queue == null || opt.queue === true ) {
opt.queue = "fx";
}
// Queueing
opt.old = opt.complete;
//最终回调实际包含两个操作步骤:1执行添加的回调函数;2进行出队操作
opt.complete = function() {
if ( jQuery.isFunction( opt.old ) ) {
opt.old.call( this );
}
if ( opt.queue ) {
jQuery.dequeue( this, opt.queue );
}
};
return opt;
};
tweeners主要处理两种情况:
$('#div1').animate({ width : '50%' },2000);//将宽度先转化成百分数格式,在过渡到50%
$('#div1').animate({ width : '+=200' },2000);//在原有基础上加200
propFilter()主要处理一下几种情况:
//转驼峰处理
$('#div1').animate({ 'margin-left' : 200 },2000); // margin-left-> marginLeft
//复合属性的拆分
$('#div1').animate({ 'margin' : 200 },2000); //marginLeft marginTop marginBottom marginRight
//设置独立的运动形式
$('#div1').animate({ 'width' : [200,'linear'] , 'height' : [20,'swing'] },2000);
$('#div1').animate({ 'width' : 200 , 'height' : 20 },{
specialEasing : {
'width' : 'linear',
'height' : 'swing'
}
});
defaultPrefilter()处理下列情况
//宽度和高度同时变化
$('#div1').animate({ 'width' : 300 },{
queue : false
}).animate({ 'height' : 300 },{});
stop([clearQueue],[goToEnd]):停止运动
当直接使用stop(),没有参数时,停止当
前正在进行的动画,但是还会执行队列后面的动画
案例中队列中有两个动画,第一个是宽度增加,第二个是高度增加,当点击start按钮,2秒内点击stop按钮:运动情况是第一个动画立刻停止,宽度不再增加增加,第二个动画开始,高度逐渐增加。
<button type="button" id="start">start</button>
<button type="button" id="stop">stop</button>
<div id="box" style="width: 100px; height: 100px;background-color: red;">Animate</div>
<script type="text/javascript">
$('#start').click(function(){
$('#box').animate({'width':'500px'},2000)
.animate({'height':'500px'},3000);
});
$('#stop').click(function(){
$('#box').stop();
})
当第一个参数是true时,表示清除队列,该队列所有动画都会停止执行
当点击start按钮,2秒内点击stop按钮:运动情况是第一个动画立刻停止,宽度不再增加增加,同时后面的动画也不会执行,因为已经清空动画队列了。
<button type="button" id="start">start</button>
<button type="button" id="stop">stop</button>
<div id="box" style="width: 100px; height: 100px;background-color: red;">Animate</div>
<script type="text/javascript">
$('#start').click(function(){
$('#box').animate({'width':'500px'},2000)
.animate({'height':'500px'},3000);
});
$('#stop').click(function(){
$('#box').stop(true);
})
当第二个参数是true时,表示将正在执行的动画跳到末状态
注意:只是将当前运动的动画跳到末状态,不会将后面的动画也跳到末状态
stop(false,true)
点击star按钮后,2秒内点击stop,宽度直接变成500px,第二个动画开始执行,高度逐渐增加到500px。
<button type="button" id="start">start</button>
<button type="button" id="stop">stop</button>
<div id="box" style="width: 100px; height: 100px;background-color: red;">Animate</div>
<script type="text/javascript">
$('#start').click(function(){
$('#box').animate({'width':'500px'},2000)
.animate({'height':'500px'},3000);
});
$('#stop').click(function(){
$('#box').stop(false,true);
})
stop(true,true)
点击star按钮后,2秒内点击stop,宽度直接变成500px,后面的动画不在执行,高度仍然是100px
<button type="button" id="start">start</button>
<button type="button" id="stop">stop</button>
<div id="box" style="width: 100px; height: 100px;background-color: red;">Animate</div>
<script type="text/javascript">
$('#start').click(function(){
$('#box').animate({'width':'500px'},2000)
.animate({'height':'500px'},3000);
});
$('#stop').click(function(){
$('#box').stop(true,true);
})