a.动画兼容Tween.propHooks
Tween.propHooks提供特殊情况下设置、获取css特征值的方法,结构如下
Tween.propHooks = {
_default: {
get: function(){...},
set: function(){...}
},
scrollTop: {
set: function(){...}
}
scrollLeft: {
set: function(){...}
}
}
Tween.propHooks.scrollTop 和Tween.propHooks.scrollLeft两个主要是在ie8离线状态下会出现混乱而把css特征值保存到节点上
set: function( tween ) {
if ( tween.elem.nodeType && tween.elem.parentNode ) {
tween.elem[ tween.prop ] = tween.now;
}
}
Tween.propHooks._default的get方法会尝试直接从节点上取得css的tween.prop特征值,如果取不到则使用jQuery.css()方式来获取。该方法处理中,简单的值如“10px”会被解析为浮点数;复杂的值,如“旋转(1rad)”返回原样。并对返回结果再做处理:空字符串, null, undefined 和 "auto"都转化为0;其他情况不变。
get: function( tween ) {
var result;
if ( tween.elem[ tween.prop ] != null &&
(!tween.elem.style || tween.elem.style[ tween.prop ] == null) ) {
return tween.elem[ tween.prop ];
}
//传递一个空字符串作为第三个参数的.css会自动尝试parseFloat,
//并返回到一个字符串,如果解析失败的话。
//所以,简单的值,如“10px”会被被解析为浮点数。复杂的值,如“旋转(1rad)”返回原样。
result = jQuery.css( tween.elem, tween.prop, "" );
// 空字符串, null, undefined 和 "auto"都转化为0
return !result || result === "auto" ? 0 : result;
}
Tween.propHooks._default的set方法先会尝试jQuery.fx.step[ tween.prop ]来设置向下兼容;否则会使用jQuery.style来设置css特征值;最极端情况则会将特征值直接保存在节点上
set: function( tween ) {
//使用step hook向下兼容 - 使用cssHook如果他存在 - 使用.style如果可用的话
//使用直接的特征值如果可用可用的话
if ( jQuery.fx.step[ tween.prop ] ) {
jQuery.fx.step[ tween.prop ]( tween );
} else if ( tween.elem.style && ( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null || jQuery.cssHooks[ tween.prop ] ) ) {
jQuery.style( tween.elem, tween.prop, tween.now + tween.unit );
} else {
tween.elem[ tween.prop ] = tween.now;
}
}
b. 动画专用对象jQuery.fx
jQuery.fx封装了一些用来执行动画动作的函数,结构如下
jQuery.fx = {
tick = function () {...},//每个时间点都会执行的函数外壳,会取出jQuery.timers中的函数执行
timer = function ( timer ) {...},//执行参数中的函数并启动计时
interval = 13, //计时步长
start = function () {...},//启动计时
stop = function () {...},//停止计时
speeds = {slow: 600,fast: 200,_default: 400},//动画速度(完整动画执行时间)
step = {}//向下兼容<1.8扩展点
}
详细的源码分析如下
jQuery.fx = Tween.prototype.init;
//每个时间点都会执行的函数外壳,会取出jQuery.timers中的函数执行
jQuery.fx.tick = function() {
var timer,
timers = jQuery.timers,
i = 0;
fxNow = jQuery.now();
for ( ; i < timers.length; i++ ) {
timer = timers[ i ];
// Checks the timer has not already been removed
if ( !timer() && timers[ i ] === timer ) {
timers.splice( i--, 1 );
}
}
if ( !timers.length ) {
jQuery.fx.stop();
}
fxNow = undefined;
};
//执行参数中的函数并启动计时
jQuery.fx.timer = function( timer ) {
if ( timer() && jQuery.timers.push( timer ) ) {
jQuery.fx.start();
}
};
//计时步长
jQuery.fx.interval = 13;
//启动计时
jQuery.fx.start = function() {
if ( !timerId ) {
timerId = setInterval( jQuery.fx.tick, jQuery.fx.interval );
}
};
//停止计时
jQuery.fx.stop = function() {
clearInterval( timerId );
timerId = null;
};
//动画速度(完整动画执行时间)
jQuery.fx.speeds = {
slow: 600,
fast: 200,
// Default speed
_default: 400
};
//向下兼容<1.8扩展点
jQuery.fx.step = {};
这里其中执行动画的关键源码是
//动画入口函数function Animation( elem, properties, options ){
...
jQuery.fx.timer(
jQuery.extend( tick, {
elem: elem,
anim: animation,
queue: animation.opts.queue
})
);
...
}
//执行参数中的函数并启动计时
jQuery.fx.timer = function( timer ) {
if ( timer() && jQuery.timers.push( timer ) ) {
jQuery.fx.start();
}
};
//计时步长
jQuery.fx.interval = 13;
//启动计时
jQuery.fx.start = function() {
if ( !timerId ) {
timerId = setInterval( jQuery.fx.tick, jQuery.fx.interval );
}
};
变量jQuery.timers = [];用来保存每次tick需要执行的函数列表。一般来说就只有一个函数,就是Animation函数中定义的tick函数。jQuery.fx.interval可以用来设置动画每两帧之间的时间间隔,默认为13毫秒。
动画的分析就到这里。下面把动画相关的api列一下
jQuery.fn.show([ duration ] [, easing ] [, complete ] | options )(显示所有匹配的元素。此外,你还可以指定元素显示的过渡动画效果。如果元素本身是可见的,则不对其作任何改变。如果元素是隐藏的,则使其可见。与该函数相对的是hide()函数,用于隐藏所有匹配的元素)
jQuery.fn.hide([ duration ] [, easing ] [, complete ] | options)(隐藏所有匹配的元素。此外,你还可以指定元素隐藏的过渡动画效果。如果元素本身是不可见的,则不对其作任何改变。如果元素是可见的,则将其隐藏。)
jQuery.fn.toggle([ duration ] [, easing ] [, complete ] | options)(切换所有匹配的元素。此外,你还可以指定元素切换的过渡动画效果。所谓"切换",也就是如果元素当前是可见的,则将其隐藏;如果元素当前是隐藏的,则使其显示(可见)。)
这里介绍的toggle()函数用于切换元素的显示/隐藏。jQuery还有一个同名的事件函数toggle(),用于绑定click事件并在触发时轮流切换执行不同的事件处理函数。
jQuery.fn.slideDown([ duration ] [, easing ] [, complete ] | options)(显示所有匹配的元素,并带有向下滑动的过渡动画效果。向下滑动的动画效果,即元素可见区域的高度从0逐渐增大到其原有高度(向下逐渐展开)。如果元素本身是可见的,则不对其作任何改变。如果元素是隐藏的,则使其可见。
与该函数相对的是slideUp()函数,用于隐藏所有匹配的元素,并带有向上滑动的过渡动画效果)
jQuery.fn.slideUp([ duration ] [, easing ] [, complete ] | options)(隐藏所有匹配的元素,并带有向上滑动的过渡动画效果。向上滑动的动画效果,即元素可见区域的高度从原有高度逐渐减小到0(向上逐渐收起)。如果元素本身是隐藏的,则不对其作任何改变。如果元素是可见的,则将其隐藏)
jQuery.fn.slideToggle([ duration ] [, easing ] [, complete ] | options)(切换所有匹配的元素,并带有滑动的过渡动画效果。所谓"切换",也就是如果元素当前是可见的,则将其隐藏(向上滑动);如果元素当前是隐藏的,则使其显示(向下滑动))
jQuery.fn.fadeIn([ duration ] [, easing ] [, complete ] | options)(显示所有匹配的元素,并带有淡入的过渡动画效果。淡入的动画效果,即元素的不透明度的比例从0%逐渐增加到100%。如果元素本身是可见的,则不对其作任何改变。如果元素是隐藏的,则使其可见。与该函数相对的是fadeOut()函数,用于隐藏所有匹配的元素,并带有淡出的过渡动画效果)
jQuery.fn.fadeOut([ duration ] [, easing ] [, complete ] | options)(隐藏所有匹配的元素,并带有淡出的过渡动画效果。所谓"淡出"的动画效果,即元素的不透明度的比例从100%逐渐减小到0%。如果元素本身是隐藏的,则不对其作任何改变。如果元素是可见的,则将其隐藏)
jQuery.fn.fadeToggle([ duration ] [, easing ] [, complete ] | options)(切换所有匹配的元素,并带有淡入/淡出的过渡动画效果。所谓"切换",即如果元素当前是可见的,则将其隐藏(淡出);如果元素当前是隐藏的,则使其显示(淡入))
jQuery.fn.animate(cssProperties [, duration ] [, easing ] [, complete ] | cssProperties, options)(执行一个基于css属性的自定义动画。你可以为匹配的元素设置css样式,animate()函数将会执行一个从当前样式到指定的css样式的一个过渡动画。例如:某个div元素的当前高度为100px,将其CSS height属性设为200px,animate()将会执行一个将div元素的高度从100px逐渐增加到200px的过渡
您可能想查找下面的文章:
- jQuery1.9.1源码分析系列(十六)ajax之ajax框架
- Jquery1.9.1源码分析系列(十五)动画处理之外篇
- jQuery 1.9.1源码分析系列(十五)之动画处理
- jQuery 1.9.1源码分析系列(十五)动画处理之缓动动画核心Tween
- jQuery 1.9.1源码分析系列(十四)之常用jQuery工具
- jQuery 1.9.1源码分析系列(十三)之位置大小操作
- Jquery 1.9.1源码分析系列(十二)之筛选操作
- jQuery-1.9.1源码分析系列(十一)DOM操作续之克隆节点
- jQuery 1.9.1源码分析系列(十)事件系统之主动触发事件和模拟冒泡处理
- Jquery1.9.1源码分析系列(六)延时对象应用之jQuery.ready

