**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()