JavaScipt 動畫引擎

來源:互聯網
上載者:User

標籤:cal   線性表   它的   ajax   type   基礎   err   anim   功能   

隊列操作

jquery中有一個Queue隊列的介面,這個模組沒有單獨拿出來作為一個章節是因為這個是內部專門為動畫服務的,Queue隊列如同data資料緩衝與Deferred非同步模型一樣,都是jQuery庫的內部實現的基礎設施

Queue隊列

隊列是一種特殊的線性表,只允許在表的前端(隊頭)進行刪除操作(出隊),在表的後端(隊尾)進行出入操作(入隊),隊列的特點是先進先出,最先插入的元素最先被刪除。

為什麼要引入隊列

var a = 1;

setTimeout(function(){

  a=2;

},0)

alert(a);

我們一直習慣於線性編寫代碼邏輯,但是在JavaScript編程幾乎總是伴隨著非同步作業:

setTImeout,css3Transition/Animation,ajax,dom的繪製,postmessage,web Database 等等,大量非同步作業所帶來的回呼函數會把我們的演算法分解,對於“非同步+回調”的模式,怎麼“拉平”非同步作業使之跟同步一樣,因為非同步作業進行流程式控制制的時候無非避免的要嵌套大量的回調邏輯,所以就會出現 promises 約定了。

那麼 jQuery 引入隊列其實從一個角度上可以認為:允許一系列函數被非同步地調用而不會阻塞程式。

看一個程式碼片段:

$("#Aaron").slideUp().fadeIn()

這是 jQuery 的一組動畫鏈式序列,它的內部其實就是一組隊列 Queue,所以隊列和 Deferred 地位類似,是一個內部使用的基礎設施。

  • 當 slideUp 運行時,fadeIn 被放到 fx 隊列中
  • 當 slideUp 完成後,從隊列中被取出運行

Queue 函數允許直接操作這個鏈式調用的行為,同時 Queue 可以指定隊列名稱獲得其他能力而不局限於 fx 隊列。

jQuery 提供了 2 組隊列操作的 API:

jQuery.queue/dequeuejQuery.fn.queue/dequeue

但是不同與普通隊列定義的是:

  • jQuery.queue 和 jQuery.fn.queue 不僅執行出隊操作返回隊頭元素,還會自動執行返回的隊頭元素
  • fn 是擴充在原型上的進階API是提供給執行個體使用的
  • .queue/.dequeue 其內部是調用的 .queue,.dequeue 靜態底層方法實現入列與出列

queue與dequeue

$.queue:顯示或操作匹配的元素上已經執行的函數隊列這個方法有兩個作用,它既是setter,又是getter,第一個參數elem是DOM元素,第二個參數type是字串,第三個參數data可以是function或數組。

var body  = $(‘body‘);

function cb1(){alert(1)}

function cb2(){alert(2)}

 

//set 第三個參數是函數

$.queue(body,‘aa‘,cb1);

$.queue(body,‘aa‘cb2);

//get

$.queue(body,‘aa‘);

這個方法有點類型get有點類似隊列的push操作,jQuery的方法的介面重載是非常嚴重的,經常同一個介面既是set也是get,不管符不符合基本原則,但是它卻很實用,無非就是把資料給緩衝起來,為什麼載體是一個jQuery對象,因為儲存資料的手段是通過data資料緩衝實現的

data 與 jQuery 對象之間是通過 uuid 建立了一個無耦合的映射關係,具體可以翻閱之前的關於“資料緩衝”,源碼有一個預設處理 type = (type || "fx") + "queue" 可見是專職供fx動畫隊列處理的。

這裡有一個hooks?
仔細分析下這個內部 queueHooks
_queueHooks: function(elem, type) {    var key = type + "queueHooks";    return data_priv.get(elem, key) || data_priv.access(elem, key, {        empty: jQuery.Callbacks("once memory").add(function() {            data_priv.remove(elem, [type + "queue", key]);        })    });}
我們說了dequeue不僅是取出來還需要執行,在執行的時候把next與hooks傳遞給外部的回調,這就是js的邏輯上的很繞的地方,在內部可以傳遞一個引用出去,又能提供外部調用或者執行。
fn.call(elem, next, hooks)
因為傳遞了next,所以我們的代碼可以參考右邊代碼,next內部仍然調用$.dequeue,這樣可以接著執行隊列中的下一個 callback,$.dequeue 裡的 hooks 是當隊列裡所有的 callback 都執行完後(此時 startLength 為0)進行最後的一個清理工作。
if ( !startLength && hooks ) {    hooks.empty.fire();}
鉤子其實就是 jQuery.Callbacks 對象,可以實現一個收集器的功能,至於在什麼情況下時候,之後動畫中開始分析,所以隊列的本質是利用 Array 的 push 和 shift 來完成先進先出(First In First Out),但是這個方法的缺點也很明顯,無法單獨做一個獨立的模組處理,因為它必須要跟 jQuery 對象吻合,而且對傳遞的資料只能是函數。  

JavaScipt 動畫引擎

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.