jQuery1.5.1 animate方法源碼閱讀
更新時(shí)間:2011年04月05日 21:40:38 作者:
jquery本身的動畫較之mootools,總體上感覺稍微有點(diǎn)遜色,不過因?yàn)槠溆袕?qiáng)大的插件,加上API易讀型,易用性等備受青睞,在動畫效果方面,API提供了比如一些比較實(shí)用的Effects,下面是main方法animate
復(fù)制代碼 代碼如下:
/*7536-7646*/
animate: function( prop, speed, easing, callback ) {
if ( jQuery.isEmptyObject( prop ) ) {
return this.each( optall.complete );
}
//#7864行this.options.complete.call( this.elem )使得其可以不斷的連續(xù)執(zhí)行動畫,比如$(‘selector').animate({prop1},speed1).animate({prop2},speed2)這樣的動畫隊(duì)列;
return this[ optall.queue === false ? "each" : "queue" ](function() {
// XXX 'this' does not always have a nodeName when running the
// test suite
var opt = jQuery.extend({}, optall), p,
isElement = this.nodeType === 1,
hidden = isElement && jQuery(this).is(":hidden"),
self = this;
//要執(zhí)行動畫的prop,prop一般是一個(gè)plainObj,形如{key1:value1,key2:value2};
for ( p in prop ) {
//駝峰改寫,有些比如magrin-top需要變成駝峰的屬性即變成marginTop;見cameCase方法;
var name = jQuery.camelCase( p );
//fix屬性;主要是前面camelcase的屬性;
if ( p !== name ) {
prop[ name ] = prop[ p ];
delete prop[ p ];
p = name;
}
//如果執(zhí)行$(..).show||$(..).hide;如果這個(gè)元素本身是hidden,而動畫里面又寫hide,直接運(yùn)行callbacks就可以了;
if ( prop[p] === "hide" && hidden || prop[p] === "show" && !hidden ) {
return opt.complete.call(this);
}
//如果prop[key]==(height||width)并且是一個(gè)dom元素;需要有些特殊的處理;
if ( isElement && ( p === "height" || p === "width" ) ) {
// Make sure that nothing sneaks out
// Record all 3 overflow attributes because IE does not
// change the overflow attribute when overflowX and
// overflowY are set to the same value
opt.overflow = [ this.style.overflow, this.style.overflowX, this.style.overflowY ];
// Set display property to inline-block for height/width
// animations on inline elements that are having width/height
// animated
if ( jQuery.css( this, "display" ) === "inline" &&
jQuery.css( this, "float" ) === "none" ) {
if ( !jQuery.support.inlineBlockNeedsLayout ) {
this.style.display = "inline-block";
} else {
var display = defaultDisplay(this.nodeName);
// inline-level elements accept inline-block;
// block-level elements need to be inline with layout
if ( display === "inline" ) {
this.style.display = "inline-block";
} else {
this.style.display = "inline";
this.style.zoom = 1;
}
}
}
}
//如果prop[key]是一個(gè)數(shù)組;只用第一個(gè)值prop[p][0];
if ( jQuery.isArray( prop[p] ) ) {
// Create (if needed) and add to specialEasing
(opt.specialEasing = opt.specialEasing || {})[p] = prop[p][1];
prop[p] = prop[p][0];
}
}
if ( opt.overflow != null ) {
//如果動畫元素的overflow已經(jīng)被設(shè)置的情況下,把它暫時(shí)為hidden;
this.style.overflow = "hidden";
}
//當(dāng)前動畫鍵值對,其實(shí)就是prop;
opt.curAnim = jQuery.extend({}, prop);
//這里便是動畫的核心了,對每一個(gè)prop[key]進(jìn)行處理;
jQuery.each( prop, function( name, val ) {
//獲取一個(gè)Fx對象;傳入的每一個(gè)參數(shù)都被設(shè)置成為這個(gè)對象的屬性;其中self是指動畫元素自身;opt是前面產(chǎn)生的對象;
var e = new jQuery.fx( self, opt, name );
//當(dāng)執(zhí)行show||hide操作的時(shí)候prop==fxAttrs(參見show||hide方法)
if ( rfxtypes.test(val) ) {
e[ val === "toggle" ? hidden ? "show" : "hide" : val ]( prop );
} else {
var parts = rfxnum.exec(val),
//start保存了初始值,它可能在style,也可能在css中,如果該值==null,undefiend,auto,0等將被設(shè)置為0;
start = e.cur();
if ( parts ) {
//end是指變化量的大小,比如:{left:-=66px},那么end=66;
var end = parseFloat( parts[2] ),
//單元運(yùn)算符,就是px,%;如果是一些不能帶單位的,比如z-index,設(shè)置為空,否則就設(shè)置為px;
unit = parts[3] || ( jQuery.cssNumber[ name ] ? "" : "px" );
// We need to compute starting value
//如果不是px,比如%,em等等;
if ( unit !== "px" ) {
//設(shè)置該屬性值name為(end || 1) + unit,如果end=0;設(shè)置為1;開始值被設(shè)置為start = ((end || 1) / e.cur()) * start;
jQuery.style( self, name, (end || 1) + unit);
//這里e.cur()和前面的start = e.cur();是不一樣的,因?yàn)閖Query.style( self, name, (end || 1) + unit)的執(zhí)行使得start被改變;用于處理end=0的情況;因?yàn)閑.cur()作為除數(shù),不能為0;
start = ((end || 1) / e.cur()) * start;
jQuery.style( self, name, start + unit);
}
// If a +=/-= token was provided, we're doing a relative animation
if ( parts[1] ) {
//end相應(yīng)的被設(shè)置為運(yùn)算后的變量值;
end = ((parts[1] === "-=" ? -1 : 1) * end) + start;
}
e.custom( start, end, unit );
//如果沒有數(shù)字化的運(yùn)算;那么沒傳入的只能是'';
} else {
e.custom( start, val, "" );
}
}
});
// For JS strict compliance
return true;
});
},
相關(guān)文章
jquery插件沖突(jquery.noconflict)解決方法分享
本文主要解決了如何讓多個(gè)不同的jQuery版本在同一個(gè)頁面并存而不沖突的方法,需要的朋友可以參考下2014-03-03jQuery實(shí)現(xiàn)多張圖片上傳預(yù)覽(不經(jīng)過后端處理)
本篇文章主要介紹了jQuery實(shí)現(xiàn)多張圖片上傳預(yù)覽(不經(jīng)過后端處理)的相關(guān)知識。具有很好的參考價(jià)值。下面跟著小編一起來看下吧2017-04-04基于jQuery的倒計(jì)時(shí)實(shí)現(xiàn)代碼
昨天看了妙味課堂的倒計(jì)時(shí)視頻,自己學(xué)著寫了下,需要的朋友可以參考下2012-05-05bootstrap中日歷范圍選擇插件daterangepicker的使用詳解
daterangepicker是bootstrap的一個(gè)日歷插件 主要用來選擇時(shí)間段的插件 這個(gè)插件很好用也很容易操作 。這篇文章主要介紹了bootstrap中日歷范圍選擇插件daterangepicker的使用詳解,需要的朋友可以參考下2018-04-04jQuery Easyui Datagrid實(shí)現(xiàn)單行的上移下移及保存移動的結(jié)果
這篇文章主要介紹了jQuery Easyui Datagrid實(shí)現(xiàn)單行的上移下移及保存移動的結(jié)果,非常不錯,具有參考借鑒價(jià)值,需要的朋友可以參考下2016-08-08