天天看點

jQuery源碼分析系列(39) : 動畫隊列

data函數在jQuery中隻有短短的300行代碼,非常不起點 ,剖析源碼的時候你會發現jQuery隻要在有需要儲存資料的地方無時無刻不依賴這個基礎設施

動畫會調用隊列,隊列會調用data資料接口還儲存隊列裡面的的動畫資料

是以我們在自習回顧下關于資料緩存

<a></a>

data在jQuery中有兩種

一個是用來存資料的, 對應的對象分别是

另一個是用來存事件的,動畫資料的

<code>data_user</code>和<code>data_priv</code>, 就如其名, 一個是使用者用的, 一個是jQuery私有的, 他們都是一個叫Data的執行個體對象

為什麼要設定這2個資料接口類?

jQuery的設定都是維護一個jQuery的資料對象,是以

隻是實作data的接口,比如:

實作鍊式的.data接口,這種很簡單,我們可以把簡單的資料緩存到jquery内部的這個對象上

方法可以這樣實作

直接在執行個體上fn的接口上擴充

這個很簡單把資料直接儲存在dom對象上

當然針對基本類型這樣處理當然也是可以的,如果是引用類型,函數對象呢?這樣處理可以嗎?

問題來了:

1:這樣會更改DOM本身的屬性值,當然能不能生效還不說

2:傳遞可是引用類型哦,不靠譜的記憶體回收,說不定就溢出了

3:資料暴露,容易被直接改寫

如何解決這些問題? jQuery就引入了資料對象這個概念

先不管内部怎麼實作,先看節點的屬性

jQuery源碼分析系列(39) : 動畫隊列

多了一個灰色的自定義的key與value

灰色意味着不能通過for枚舉出來,這種設定在ES5中,是有API直接支援了

看注釋就清晰了,這個屬性是受保護的,不能被改寫

OK了。通過這樣一個唯一的橋接标志,我們可以做一個ORM的映射了,讓dom與一個資料緩存接口産生一一對應的關系

動畫隊列用到的資料緩存

jQuery為了實作動畫隊列的鍊式調用,是以必須先在執行個體就是原型上先擴充一個方法啊,然後在内部才能調用底層的方法

當然jQuery基本所有的層次都是這樣的結構,除了鍊式之外,還可以把具體的執行個體方法與原型方法通用

動畫的執行個體方法

調用執行個體方法中基于動畫的擴充接口

執行個體的queue接口隻是做了2個情況的判斷,一種是傳遞fx,一種是設定隊列,底層還是通過jQuery.queue靜态方法處理的

分析一組動畫:

1 有時間參數的接口,是肯定需要執行動畫的,同一個接口上有多個動畫接口,那麼就會意味着需要隊列來管理執行順序

2 管理隊列引入資料緩存,緩存需要載體node節點,是以動畫的擴充的接口在最上層設計是可以直接跟DOM鍊式

邏輯上肯定是線性的執行,show執行完畢,然後取出hide執行,完畢後在取出show執行

那麼動畫的調用是如何組織的?

理論上3個動畫,在cache中有3個緩存的data我們檢視下

為了便于檢視,我把代碼改了下 增加了一個标示 Aaron 對應的是時間

在執行div.show(3000)的時候,我們檢視下緩存

jQuery源碼分析系列(39) : 動畫隊列

發現0位置的div.show(1000);被inprogress給替代了

可以猜測下第一個動畫已經在開始執行了,那麼它在隊列中會用一個占位符用來通知後面,我這個動畫還在進行,後面的動畫先等等

inprogress”程序鎖是這樣工作的:

如果是dequeue操作, 去掉鎖, 執行隊列裡的函數, 同時給隊列加上鎖. 如果是queue操作, 要看鎖的狀态, 如果被鎖上了, 就隻執行隊列的添加操作. 不再調用dequeue.其實dequeue和queue都可以執行隊列裡的第一個函數.queue操作添加完隊列之後, 會調用dequeue方法去執行函數.

用dequeue執行函數的時候, 這時候如果又用queue觸發dequeue的話, 很可能同時有2個函數在執行. 隊列就失去一大半意義了(還是可以保證順序, 但是2個動畫會同時執行).不過這個鎖隻能保證在dequeue的時候, 不被queue操作意外的破壞隊列.

如果人為的同時用2個dequeue, 還是會破壞動畫效果的. 是以要把fn寫在回調函數裡

我們在第一次做push的時候就會開始執行了動畫,這樣可以讓速度更優

.queue(1000) , .queue(2000) , queue(3000)

當第一個動畫執行完畢後,那麼必須有一個回調通知這個去把隊列中下一個執行給取出來,然後要删掉這個占位,依次循環

是以可見,動畫的執行其實最終是依賴queue與dequeue的處理,隻是說在執行開始與執行完畢做了一個流程的控制

具體動畫内部怎麼執行的,從下章開始分析

本文轉自艾倫 Aaron部落格園部落格,原文連結:http://www.cnblogs.com/aaronjs/p/3813237.html,如需轉載請自行聯系原作者

繼續閱讀