我的模塊加載系統 v23發布,主要改進以下
- 支持動態添加加載器,正確取得加載器所在的節點的路徑
- 修正IE6加態加載模塊的BUG
- 對parseURL進行優化,減少對正則的依賴,提高性能。
- 對跨域的容錯更強,減少對top的訪問,因為如果加載器是放在iframe中,而iframe與套嵌它的父頁面不同域,就會拋錯。
目前重構文檔中,為了總是指向正確的路徑,不得不使用document.write,這時原來的最后一個script標簽的方式就會出錯!
<script>
window.$$path = location.protocol + "//" + location.host;
document.write('<script src="' + $$path + '/mass.js"><\/script>')
document.write('<script src="' + $$path + '/doc/scripts/common.js"><\/script>')
</script>
我們想得到包含“/mass.js”這節點的路徑,原來的取法為:
(function(scripts) {
var cur = scripts[scripts.length - 1],//★★★★★★
url = (cur.hasAttribute ? cur.src : cur.getAttribute("src", 4)).replace(/[?#].*/, ""),
kernel = $.config;
basepath = kernel.base = url.slice(0, url.lastIndexOf("/") + 1);
kernel.nick = cur.getAttribute("nick") || "$";
kernel.alias = {};
kernel.level = 9;
})(DOC.getElementsByTagName("script"));
看星星處,絕對大數加載庫都是這樣取,但在上述場合中,它就有很大可能取得“/doc/scripts/common.js”這個節點。
因此我復用了內部的getCurrentScript方法,改為:
(function() {
var cur = getCurrentScript(true)
var url = cur.replace(/[?#].*/, "");
kernel = $.config;
basepath = kernel.base = url.slice(0, url.lastIndexOf("/") + 1);
var scripts = DOC.getElementsByTagName("script");
for (var i = 0, el; el = scripts[i++]; ) {
if (el.src === cur) {
kernel.nick = el.getAttribute("nick") || "$";
break;
}
}
kernel.alias = {};
kernel.level = 9;
})();
至於動態加載,網友在IE6提出了一個BUG,經過一番調戲,發現它竟然沒有進入checkDeps方法。現在默認至少進入一次checkDeps,就可以避開這BUG。
按需加載模塊,點擊時才繼續加載。這個是seajs很難實現的,需要用到seajs.async,但現在好像已經移除了。
require("/doc/scripts/loadtest/aaa,/doc/scripts/loadtest/bbb,ready", function(a, b, $) {
var node = $("#loadasync");
node.append(a);
node.append(b);
$("#asynctest").click(function() {
require("/doc/scripts/loadtest/ccc,/doc/scripts/loadtest/ddd", function(c, d) {
node.append(c);
node.append(d);
});
});
});
如果嫌/doc/scripts/loadtest/這些太長太亂了,還可以利用別名機制。
var path = location.protocol + "//" + location.host +"/doc/scripts/loadtest/"
require.config({
alias: {
"aaa": path+"aaa.js",
"bbb": path+"bbb.js",
"ccc": path+"ccc.js",
"ddd": path+"ddd.js"
}
})
require("aaa,bbb,ready", function(a,b,$) {
var parent = $("#loadasync2")
parent.append(a);
parent.append(b);
$("#asynctest2").click(function(){
require("ccc,ddd", function(c, d) {
parent.append(c);
parent.append(d);
})
})
});
順便說一下,mass Framework已經朝着移動庫的方向發展。在移動端,zepto只支持webkit系,對IE10,firefox移動版支持不良。目前,最好用的庫還是Sencha Touch,不過太大了。決定自己動手豐衣足食。
