**1 文件源代碼(18 scan.js)**
~~~
avalon.scan = function(elem, vmodel) {
elem = elem || root
var vmodels = vmodel ? [].concat(vmodel) : []
scanTag(elem, vmodels)
}
var stopScan = oneObject("area,base,basefont,br,col,command,embed,hr,img,input,link,meta,param,source,track,wbr,noscript,script,style,textarea".toUpperCase())
function checkScan(elem, callback, innerHTML) {
var id = setTimeout(function() {
var currHTML = elem.innerHTML
clearTimeout(id)
if (currHTML === innerHTML) {
callback()
} else {
checkScan(elem, callback, currHTML)
}
})
}
function createSignalTower(elem, vmodel) {
var id = elem.getAttribute("avalonctrl") || vmodel.$id
elem.setAttribute("avalonctrl", id)
vmodel.$events.expr = elem.tagName + '[avalonctrl="' + id + '"]'
}
var getBindingCallback = function(elem, name, vmodels) {
var callback = elem.getAttribute(name)
if (callback) {
for (var i = 0, vm; vm = vmodels[i++]; ) {
if (vm.hasOwnProperty(callback) && typeof vm[callback] === "function") {
return vm[callback]
}
}
}
}
function executeBindings(bindings, vmodels) {
for (var i = 0, data; data = bindings[i++]; ) {
data.vmodels = vmodels
bindingHandlers[data.type](data, vmodels)
if (data.evaluator && data.element && data.element.nodeType === 1) {
data.element.removeAttribute(data.name)
}
}
bindings.length = 0
}
var mergeTextNodes = IEVersion && window.MutationObserver ? function (elem) {
var node = elem.firstChild, text
while (node) {
var aaa = node.nextSibling
if (node.nodeType === 3) {
if (text) {
text.nodeValue += node.nodeValue
elem.removeChild(node)
} else {
text = node
}
} else {
text = null
}
node = aaa
}
} : 0
var roneTime = /^\s*::/
var rmsAttr = /ms-(\w+)-?(.*)/
var priorityMap = {
"if": 10,
"repeat": 90,
"data": 100,
"widget": 110,
"each": 1400,
"with": 1500,
"duplex": 2000,
"on": 3000
}
var events = oneObject("animationend,blur,change,input,click,dblclick,focus,keydown,keypress,keyup,mousedown,mouseenter,mouseleave,mousemove,mouseout,mouseover,mouseup,scan,scroll,submit")
var obsoleteAttrs = oneObject("value,title,alt,checked,selected,disabled,readonly,enabled")
function bindingSorter(a, b) {
return a.priority - b.priority
}
~~~
**2 文件分析**
~~~
avalon.scan = function(elem, vmodel) {
elem = elem || root
var vmodels = vmodel ? [].concat(vmodel) : []
scanTag(elem, vmodels)
}
~~~
>[info] avalon.scan()是a文件掃描入口,遍歷指定節點內容,
> 添加掃描信息到vmodel
> scan()是avalon的scan() define()兩個主要接口之一
elem:待掃描標簽,vmodel掃描信息添加目標
`elem = elem || root`
>[info] 如果存在elem,從eleme掃描,否則從root開始掃描
`var vmodels = vmodel ? [].concat(vmodel) : []`
>[info] 如果傳入vmodel,連接vmodel到空數組,否則直接使用空數組保存掃描信息
`scanTag(elem, vmodels) `
>[info] 掃描elem對應的標簽內容
* * * * *
`var stopScan = oneObject("area,base,basefont,br,col,command,embed,hr,img,input,link,meta,param,source,track,wbr,noscript,script,style,textarea".toUpperCase())`
>[info] 禁止掃描的標簽對象 stopScan
~~~
checkScan()
createSignalTower()
geiBindingCallBack()
~~~
>[info] 這3個函數接口用在綁定處理過程中
`executeBindings()`
>[info] 這個函數處理綁定的核心。
>[info] bindings:待處理綁定內容
> vmodels:綁定信息關聯的vmodel
>[info]遍歷bindings數組,調用bindingHandlers數組對應的綁定函數。
>[info]下面的if語句是bug處理
>[info] 最后將待綁定數組長度設置為0
`mergeTextNodes`
>[info] MutationObserver的bug處理
~~~
var roneTime
var rmsAttr
var priorityMap
~~~
>[info]
roneTime :次數參數表達式符號
rmsAttr :待掃描屬性表達式符號
priorityMap :指令優先級數組
~~~
var events
var obsoleteAttrs
~~~
>[info] events:事件對象
obsoleteAttrs input:屬性對象
`bindingSorter()`
>[info] bindingSorter():根據優先級排序bindings數組內容
**3 總結**
> 1 思路
文件掃描主要實現了掃描入口scan()
其余的是全局變量與全局函數的聲明
> 2 接口
avalon.scan()