ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
**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()