寫angularJS源碼閱讀系列的時候,寫的太垃圾了。一個月後看,真心不忍直視,之後有機會的話得重寫。此次寫avalonJS,但願能在代碼架構層面多些一點,少上源碼、多寫思路。node
(function(DOC){ ... avalon=...//沒有var ... })(document)
具體暴露句柄方式的講解,在這裏。數據結構
源碼的末尾執行了這麼avalon.ready(function(){...})
一個函數,而這個函數的末尾爲avalon.scan(DOC.body)
因而乎,avalon
開始了讀body旅程。
在這旅程中,有scanNodes
、scanTag
、scanAttr
、scanText
、scanExpr
、scanTemplate
須要來回流轉運用。在講解讀取dom以前,咱們先了解下dom的組成,節點類型(document.nodeType):架構
節點類型(nodeType) 元素類型
1 元素element
2 屬性attr
3 文本text
8 註釋comments
9 文檔documentdom
咱們能夠經過節點類型和具體的元素標籤來斷定將要解析的和不會去解析的。函數
咱們先看scanNodes(parentElement,vmodels)
函數,他的做用是經過parentElement.firstChild``child.nextSibling
遍歷當前dom下的子節點,而且經過節點類型的斷定,各自調用scanTag
(nodeType==1)和scanText
(NodeType==8 && 存在{{...}})函數。spa
scanTag(elem, vmodels, node)
,這個函數蠻有意思的,第三個參數node是做者不想進行var聲明,直接寫在參數裏的。這個函數的做用是斷定avalon執行做用域的,做用域有三類:ms-skip
ms-import
和 ms-controller
(有優先順序),ms-important
不包含父VM,ms-controller
相反會有繼承效果。
固然,這時候遊覽器尚未執行用戶自定義的avalon.defined
,因此不會調用scanAttr
繼續旅行的。.net
scanText(textNode, text, vmodels)
,顧名思義,會具體解析解析...{{...}}...
的值。這樣的話,就會涉及avalon filter的解析,具體解析方法放在scanExpr
裏面,scanText
主要替換...{{...}}...
爲解析後的數據,而且若是有用了filter的話,會調用executeBindings
進行相應的處理。
該函數會產生一個記錄scanText解析結果的object。數據結構爲:code
{ type: "text",//類型 node: node,//替換後的element nodeType: 3,//節點類型 value: token.value, filters: token.filters //token 爲scanExpr的返回值 }
scanExpr(str)
,這個函數只要知道返回的結果格式就好。blog
scanAttr(elem, vmodels)
這個函數super重要的,他會針對avalon封裝的事件和ms-if repeat widget
等作相應的處理。會在下一章連同executeBindings一塊講解。繼承
scanTemplate
屬於模板加載,之後可能會在這裏補上或者新開一篇文章單獨講解它。
若是有遍歷dom需求的話,上面代碼可通過去除依賴處理後摘出來。基本流程:從頭到腳的開始遍歷,根據存放在dom attribute的值來斷定業務需求和vm做用域,ms-duplex屬性和{{}}作佔位符,等待渲染和佔位符替換。VMODELS object則存放着要渲染進頁面的數據。