知道動(dòng)畫處理的基本原理與算法了,那么 jQuery 在這個(gè)基礎(chǔ)上封裝擴(kuò)展,讓動(dòng)畫使用起來更靈活方便。
我歸納有幾點(diǎn):
基于 promise 的事件通知
得益于 deferred 的機(jī)制,可以讓一個(gè)對(duì)象轉(zhuǎn)化成帶有 promise 的特性,實(shí)現(xiàn)了 done/fail/always/progress 等等一系列的事件反饋接口。
這樣的設(shè)計(jì)我們并不陌生,在 ready、ajax 包括動(dòng)畫都是基于這樣的異步模型的結(jié)構(gòu):
deferred = jQuery.Deferred() //生成一個(gè)動(dòng)畫對(duì)象了 animation = deferred.promise({}) //混入動(dòng)畫的屬性與方法
那么這樣操作的一個(gè)好處就是,可以把邏輯處理都放到一塊,我們?cè)诖a的某一個(gè)環(huán)節(jié)針對(duì)特別的處理,需要臨時(shí)改變一些東西,但是在之后我們希望又恢復(fù)原樣,為了邏輯的清晰,我們可以引入 deferred.alway 方法,在某一個(gè)環(huán)節(jié)改了一個(gè)屬性,然后注冊(cè)到 alway 方法上一個(gè)完成的回調(diào)用來恢復(fù),這樣的邏輯塊是很清晰的。
增加屬性的 show/hide/toggle 的快捷方式:
style.overflow = "hidden"; anim.always(function() { //完成后恢復(fù)溢出 style.overflow = opts.overflow[0]; style.overflowX = opts.overflow[1]; style.overflowY = opts.overflow[2]; });
指定中文參數(shù)是比較特殊的,這種方式也是 jQuery 自己擴(kuò)展的行為,邏輯上也很容易處理。
ook.animate({ left: '50', height:'hide' }
height 高度在動(dòng)畫結(jié)束之后隱藏元素,那么意味著元素本身的高度 height 也是需要改變的,從初始的位置慢慢的遞減到 0 然后隱藏起來。
代碼中有這么一段,針對(duì) hide 的動(dòng)作,我們?cè)?done 之后會(huì)給元素直接隱藏起來。
//目標(biāo)是顯示 if (hidden) { jQuery(elem).show(); } else { //目標(biāo)是隱藏 anim.done(function() { jQuery(elem).hide(); }); }
其實(shí) show 與 hide 的流程是一樣的,只是針對(duì)元素在初始與結(jié)束的一個(gè)狀態(tài)的改變。
css 屬性設(shè)置獨(dú)立的緩動(dòng)函數(shù)
在動(dòng)畫預(yù)初始化之后(為了支持動(dòng)畫,臨時(shí)改變?cè)氐囊恍傩耘c狀態(tài)),我們就需要給每一個(gè)屬性生成一個(gè)獨(dú)立的緩動(dòng)對(duì)象了 createTween,主要用于封裝這個(gè)動(dòng)畫的算法與執(zhí)行的一些流程操作控制。
//生成對(duì)應(yīng)的緩動(dòng)動(dòng)畫 // createTween: function(prop, end) { var tween = jQuery.Tween(elem, animation.opts, prop, end, animation.opts.specialEasing[prop] || animation.opts.easing); //加入到緩動(dòng)隊(duì)列 animation.tweens.push(tween); return tween; }
tween 對(duì)象
通過這個(gè)結(jié)構(gòu)大概就知道了,這個(gè)就是用于生成動(dòng)畫算法所需要的一些數(shù)據(jù)與算法的具體流程控制了。
屬性預(yù)處理
我們知道元素本身在布局的時(shí)候可以用很多屬性對(duì)其設(shè)置,可是一旦進(jìn)行動(dòng)畫的話,某些屬性的設(shè)置可能會(huì)對(duì)動(dòng)畫的執(zhí)行產(chǎn)生副作用,所以針對(duì)這樣的屬性,jQuery 直接在內(nèi)部做了最優(yōu)的處理,如果我們進(jìn)行元素 height/width 變化的時(shí)候,比如 height:1,這樣的處理 jQuery 就需要針對(duì)元素做一些強(qiáng)制性的處理。
1 添加 overflow =“hidden” 2.如果設(shè)置了內(nèi)聯(lián)并且沒有設(shè)置浮動(dòng) display = "inline-block";
因?yàn)閮?nèi)容溢出與內(nèi)聯(lián)元素在執(zhí)行動(dòng)畫的時(shí)候,與這個(gè) height/width 的邏輯是符合的,當(dāng)然針對(duì)這樣的修改 jQuery 非常巧妙了用到了 deferred.always 方法,我們?cè)趫?zhí)行動(dòng)畫的時(shí)候,由于動(dòng)畫的需要改了原始的屬性,但是動(dòng)畫在結(jié)束之后,我們還是需要還原成其狀態(tài)。
deferred 量身定做的 always 方法,不管成功與失敗都會(huì)執(zhí)行這個(gè)復(fù)原的邏輯。
請(qǐng)驗(yàn)證,完成請(qǐng)求
由于請(qǐng)求次數(shù)過多,請(qǐng)先驗(yàn)證,完成再次請(qǐng)求
打開微信掃碼自動(dòng)綁定
綁定后可得到
使用 Ctrl+D 可將課程添加到書簽
舉報(bào)