我的模塊加載系統 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,不過太大了。決定自己動手豐衣足食。