本版本最重要的特性是引進了AMD規範的模塊加載器,亦即原來mass Framework 的並行加載器, 不一樣之處,它引進了requirejs的xxx!風格的插件機制,好比要延遲到DOM樹建完時觸發,是使用ready!, 要加載css文件是使用css!css_path。css
加載器在移動設備或PC的單頁應用不可或缺。根據公司內容的不徹底統計,手機等瀏覽器的性能只是PC的十分之一左右,並且測試對象仍是公司的有錢同事的手機,什麼IP,三星GALAXY。 node
在過去的一週,整合angular, requirejs遇到各類困難,最後只能到github下載了一個整合好的應用來修改。因爲沒有整合的能力,意味着咱們的angular就不能隨意升級了。所以深感自帶加載器的重要性。固然加載器一直是微博遇到的一些朋友所熱切盼望的功能。由於要同時同步兩個不是本身能掌控的項目,實在心絞力竭。c++
如今avalon項目下,除了avalon.js外,還有一個叫avalon.mobile.js的東西,它是avalon.js的優化版,專門使用HTML5時代出現的新屬性構建,再也不兼容舊式IE,IE的支持版本爲IE10,這就保證移動設備上也能流暢運行。git
好比hasClass, addClass, removeClass, toggleClass在avalon.js是這樣實現的github
hasClass: function(cls) { var el = this[0] || {} if (el.nodeType === 1) { return !!el.className && (" " + el.className + " ").indexOf(" " + cls + " ") > -1 } }, addClass: function(cls) { var node = this[0] if (cls && typeof cls === "string" && node && node.nodeType === 1) { if (!node.className) { node.className = cls } else { var a = (node.className + " " + cls).match(rnospaces) a.sort() for (var j = a.length - 1; j > 0; --j) if (a[j] === a[j - 1]) a.splice(j, 1) node.className = a.join(" ") } } return this }, removeClass: function(cls) { var node = this[0] if (cls && typeof cls > "o" && node && node.nodeType === 1 && node.className) { var classNames = (cls || "").match(rnospaces) || [] var cl = classNames.length var set = " " + node.className.match(rnospaces).join(" ") + " " for (var c = 0; c < cl; c++) { set = set.replace(" " + classNames[c] + " ", " ") } node.className = set.slice(1, set.length - 1) } return this }, toggleClass: function(value, stateVal) { var state = stateVal, className, i = 0 var classNames = value.match(rnospaces) || [] var isBool = typeof stateVal === "boolean" while ((className = classNames[i++])) { state = isBool ? state : !this.hasClass(className) this[state ? "addClass" : "removeClass"](className) } return this },
到avalon.mobile則是這樣實現:web
hasClass: function(cls) { var el = this[0] || {} return el.nodeType === 1 && el.classList.contains(cls) }, addClass: function(cls) { var el = this[0] if (cls && typeof cls === "string" && el && el.nodeType === 1) { cls.replace(rword, function(c) { el.classList.add(c) }) } return this }, removeClass: function(cls) { var node = this[0] if (cls && typeof cls > "o" && node && node.nodeType === 1 && node.className) { cls.replace(rword, function(c) { node.classList.remove(c) }) } return this }, toggleClass: function(value, stateVal) { var state = stateVal, className, i = 0 var classNames = value.match(rnospaces) || [] var isBool = typeof stateVal === "boolean" var node = this[0] || {}, classList if (classList = node.classList) { while ((className = classNames[i++])) { state = isBool ? state : !classList.contains(className) classList[state ? "add" : "remove"](className) } } return this },
attr方法在這兩個版本的實現也不同,avalon.mobile.js用到了dataset。數組
data: function(name, value) { name = "data-" + hyphen(name || "") switch (arguments.length) { case 2: this.attr(name, value) return this case 1: var val = this.attr(name) return parseData(val) case 0: var attrs = this[0].attributes, ret = {} for (var i = 0, attr; attr = attrs[i++]; ) { name = attr.name if (!name.indexOf("data-")) { name = camelize(name.slice(5)) ret[name] = parseData(attr.value) } } return ret } }, //---------------------------------------------------------- avalon.data = function(name, val) { var dataset = this[0].dataset; switch (arguments.length) { case 2: dataset[name] = val return this case 1: val = dataset[name] return parseData(val) case 0: var ret = {} for (var name in dataset) { ret[name] = parseData(dataset[name]) } return ret } }
avalon.mobile.js甚至嘗試用hidden實現visible綁定瀏覽器
if (typeof DOC.createElement("div").hidden === "boolean") { bindingHandlers.visible = function(data, vmodels) { var elem = data.element watchView(data.value, vmodels, data, function(val) { elem.hidden = !val }) } }
將來的展望,接着眼於下來的0.9版本,將嘗試增強國際化的支持與對數組元素的深層監控, avalon.mobile將嘗試使用webworker, 而後發佈正式版1.0!!!!!!!!!!ruby
迷你MVVM框架在github的倉庫https://github.com/RubyLouvre/avalon框架