快捷搜索:

Jquery源码分析---FX分析

8.1 FX的常用措施

和前面阐发的代码比拟,FX是异常让人愉快的。曩昔javaeye登岸的时刻,对其登岸窗口的淡出淡入的殊效老是想入非非。Jquery的core包中也供给了Fx的实现。

Fx的实质是继续有序改变dom元素的属性达到视觉上的效果,动态地变更起来。这些属性主如果高度,宽度,透明度和颜色(背景致和前景致)等。继续有序是和光阴相关的,也便是先在某个光阴点改变一下CSS的样式属性,下一个光阴点再改变一下样式属性,达到渐变的历程的效果。

Jquery为我们供给了几种常用的FX的函数。

Slide是滑出的动作,对付slide,jquery供给了slideDown、slideUp、slideToggle三种措施。slideDown是元素向下面垂垂地滑出,着末整个可见。slideUp是元素向上面垂垂地钻进去,着末不见。slideToggle则是这两者之间的转换了。

Fade是淡变的动作。对付Fade,jquery供给了fadeIn、fadeOut两个措施。fadeIn是从无到有垂垂地显示出全部元素。fadeOut相反,它从有到无垂垂地消掉这个元素,fade还供给了一个fadeTo用来改变透明性渐变到一个指定的值,而不是消掉。

Jquery还供给一组更强大年夜的措施。Show、hide、toggle采纳一种更为柔美的要领显示元素。Show是元素的宽度垂垂变成,同时高度也垂垂变大年夜,同时透明度也垂垂从无到不透明。这种的效果是元素从一个点垂垂变大年夜,终极完全地显示出来。Hide刚是相反,它是垂垂透明同时宽高徐徐变小,着末消掉。Toggle是两者之间的转换。

jQuery.each({

slideDown: { height:"show" },

slideUp: { height: "hide" },

slideToggle: { height: "toggle" },

fadeIn: { opacity: "show" },

fadeOut: { opacity: "hide" }

}, function( name, props ){

jQuery.fn[ name ] = function( speed, callback ){

return this.animate( props, speed, callback );

};

});

// 把所有匹配元素的不透明度以渐进要领调剂到指定的不透明度,

//并在动画完成后可选地触发一个回调函数。这个动画只调剂元素的不透明度。

fadeTo: function(speed,to,callback){

return this.animate({opacity: to}, speed, callback);

},

Slide和fade是经由过程分手改变height或opacity来完成效果的。其完成的事情义务在this.animate( props, speed, callback )上。

show

对付show和hide的,它们的效果更好一点,其代码也繁杂一点。

// show(speed,[callback])

// 以优雅的动画暗藏所有匹配的元素,并在显示完成后可选地触发一个回调函数。

// 可以根据指定的速率动态地改变每个匹配元素的高度、宽度和不透明度。

// 显示暗藏的匹配元素 show()

show: function(speed,callback){

return speed ?

this.animate({height: "show", width: "show", opacity: "show"

}, speed, callback)

: this.filter(":hidden").each(function(){

this.style.display = this.oldblock || "";

if ( jQuery.css(this,"display") == "none" ) {

var elem = jQuery("").appendTo("body");

this.style.display = elem.css("display");// 默认的显示的display

if (this.style.display == "none")// 显式地设定该tag不显示           this.style.display = "block";

elem.remove();// 上面这些的处置惩罚有没有需要呢?

}

}).end();// 回到前一个jQuery工具

},

hide: function(speed,callback){

return speed ?

this.animate({height: "hide", width: "hide", opacity: "hide"

}, speed, callback)

: this.filter(":visible").each(function(){

this.oldblock = this.oldblock || jQuery.css(this,"display");

this.style.display = "none";

}).end();

},

toggle: function( fn, fn2 ){

return jQuery.isFunction(fn) && jQuery.isFunction(fn2) ?

this._toggle.apply( this, arguments ) :// 原本的toggle

(fn ?  this.animate({height: "toggle", width: "toggle",

opacity: "toggle"}, fn, fn2)

: this.each(function(){jQuery(this)[ jQuery(this).is(":hidden") ?

"show" : "hide" ]();}

// 对每个元素都调用show,或hide函数。

)

);

},

Animate经由过程传入的参数对付jquery工具中的每个元素的每个唆使的属性都进行光阴上渐变的改变。下面就阐发此中的代码。

jQuery.speed

在①是就经由过程jquery.speed来进行参数的统一收拾。

// 主要用于帮助性的事情

speed: function(speed, easing, fn) {

var opt = speed && speed.constructor == Object ? speed : {

// coplete是至多三个参数的着末一个。看看是否传入动画完成回调的函数

complete: fn ||!fn && easing ||jQuery.isFunction( speed ) && speed,

duration: speed,// 持继的光阴,动画运行的光阴。

//找到动画中属性随光阴渐变的的算法。

easing:fn&&easing || easing && easing.constructor != Function && easing

};

//谋略出精确的duration,它支持fast,slow这样已经定义的常量

opt.duration = (opt.duration &&

(opt.duration.constructor == Number?

opt.duration :

jQuery.fx.speeds[opt.duration]))||jQuery.fx.speeds._default;

// Queueing

opt.old = opt.complete;

//这里是把complete形成了包裹,看看参数中是否指定行列步队操作,

//假如先出列,再履行complete

opt.complete = function(){

//可能经由过程参数指定queue,this指向是当前的dom元素。

if ( opt.queue !== false ) jQuery(this).dequeue();//出queue

if (jQuery.isFunction( opt.old )) opt.old.call( this );

};

return opt;

},

jquery.speed是对参数进行治理的操作函数。它首先看看speed是不是收缩型的参数如{ complete:xx, easing:xx, duration:xx}。假如不是,就根据传入的参数进行判断,组成收缩型的工具参数。

阐发上面的代码可以看出Queue的操作和each的操作是不太一样的。Each是对每个元素都履行fn函数。而queue对付每个元素都把fn函数放到自已对应的cache中fx的属性中保存,是单个的fn的话,也立马运行。在②处和each的感化差不多。

在上面的代码,它还调用了queue(this, type, fn);来实现把把fn存到this元素的data中的对应的type中去。

// 为元素加上type的array的属性,或返回取到elem上type的值

var queue = function( elem, type, array ) {

if ( elem ){

type = type || "fx";

var q = jQuery.data( elem, type + "queue" );

if ( !q || array )

q = jQuery.data( elem, type + "queue", jQuery.makeArray(array) );

}

return q;

};

这个全局的函数便是在jQuery.data进一步封装,使它支持默认的fx type和array的类数组的参数。

Jquery这里的Queue实质上没有起到什么感化。它原先可以支持一个元素的的继续履行几个Queue的函数达到更富厚的动画的效果。预计这里是没有完成。

①②③④⑤⑥⑦⑧⑨⑩

jQuery.fx

⑤处animate为dom元素的每个指定的属性都天生了一个fx工具。

// 根据参数构成一个工具

fx: function( elem, options, prop ){

this.options = options;

this.elem = elem;

this.prop = prop;

if ( !options.orig )

options.orig = {};

}

Fx函数是一个构建函数,仅仅是把参数变资源工具的属性。以便于fx工具的其它措施来应用这些参数。在⑥处便是经由过程调用fx的措施show或hidden来完成一个属性的徐徐的改变。在⑨是经由过程custom措施来直接进行一个动画。

在custom中为fx工具动态地追加了几个属性。Start和end属性指的属性值变更的开始和停止位置。这是属性值发生变更的范围。Now是在Start和end 范围的某一个点,也便是当前要比属性设定值。这个值是根据光阴的距离比率再经由过程必然的算法来得出的。pos 和state一个是位置上的比率,一个是光阴上比率,值在0~1之间。

Custom经由过程this.now = this.start;和this.update();来设肇端位置的样式属性。

// 为元素设值,更新显示

update: function(){

//可以在显示之提高行自定义的显示操作

//这里可所以改变this.now或元素的其它属性。

//改变this.now是改更改画的轨迹,改变其它的属性会有更多的效果

if ( this.options.step )

this.options.step.call( this.elem, this.now, this );

//根据this.now来改变/设值当前属性的值。也就改变了样式。

(jQuery.fx.step[this.prop] || jQuery.fx.step._default)( this );

// 对付高度和宽度,肯定是要能看出效果的,故采纳display=block。

if ( ( this.prop == "height" || this.prop == "width" )

&& this.elem.style )

this.elem.style.display = "block";

},

经由过程udate设定肇端位置的样式属性之后,custom第二步便是采纳setInterval

每隔13ms就履行一次当前的fx工具的step措施。该措施实现了动画停止的收尾事情和动画历程中按必然的算法来谋略this.now的值。由于这个值的改变,之后调用update就可以改变样式的属性。

这样一来,就实现了元素的某个属性的渐变历程。

Step中第一部分是完成时的收尾事情,规复动画时改变的属性和运行complete的回调函数。第二部分便是谋略this.now的值之后显示出来。今朝jquery供给了两种算法来谋略从光阴距离比率转换成位置上的比率。

easing: {

linear: function( p, n, firstNum, diff ) {

return firstNum + diff * p;

},

swing: function( p, n, firstNum, diff ) {

return ((-Math.cos(p*Math.PI)/2) + 0.5) * diff + firstNum;

}

},

这便是它的算法。对付linear的形式,Jquery采纳了1:1的关系来谋略的。

Stop

一个动画,有的光阴可能会呈现在没有运行完成绩中断。Stop便是对这个进行操作的。

stop: function(clearQueue, gotoEnd){

var timers = jQuery.timers;

if (clearQueue)  this.queue([]);// 清除

this.each(function(){

//倒序是为了能把在loop历程加入timers确当前元素的属性的动画step也给删除。

for ( var i = timers.length - 1; i >= 0; i-- )

if ( timers[i].elem == this ) {

if (gotoEnd) timers[i](true); // 逼迫动画停止

timers.splice(i, 1);

}

});

// start the next in the queue if the last step wasn't forced

if (!gotoEnd)   this.dequeue();

return this;

}

在stop中,我们可以看出step(force)中的参数的感化。这个逼迫动画到着末一步,即动画停止进行收尾事情。这里的jQuery.timers是公共的聚拢。在custom中的setInterval便是对它进行操作的。

文章滥觞:http://jljlpch.javaeye.com/category/37744

您可能还会对下面的文章感兴趣: