重構中的事情:
1、首先,整個項目的頁腳頁頭都有用到一些js和js庫,這些具有共性的js先抽離到一個獨立的head.js與foot.js中,放到include文件夾下。
2、對于公用的js庫,如jquery,blockUI,jquery-template,日歷控件等,先通過<script>標簽依次放置于foot.jsp中。
3、對于強交互的頁面,將其js文件放在include平級的目錄下,以該項目名命名, 如app。
4、第一步的腳本分離工作就完成了,但這只是萬里長征的第一步,接下來就需要管理好這些依賴和合理組織其中的代碼結構了。
5、對于js庫的管理,可以用lab.js或require.js,在本次重構中,兩者都使用了。由于從jsp重分離出來的js代碼沒有良好的組織,其對第三方庫的依賴也很難一時理清。
再者,重構之事,有時間上的要求,只要分階段走了。先保證js分離后能夠不影響項目正常運行,然后再一步步合理優化代碼。
6、于是使用了lab.js,理由是可以按原頁面要求的加載順序來加載第三方js庫,這樣可以確保抽離出來的js能在lab.js加載相關庫后,正確的運行。
foot.jsp中定義了全局變量
1 <script type="text/javascript">
2 var username = "${loginUser.username}";
3 var version = "${version}";
4 </script>
5 <script type="text/javascript" src="${staticJsRoot}/common/LAB.min.js?${version}"></script>
6 <script type="text/javascript">
7 //供其他包含頁面使用,確保在一個依賴請求鏈條內
8 $LAB = $LAB.script(LOCATION.js+"/common/jquery-1.6.1.min.js?"+version).wait()//確保順序加載
9 .script(LOCATION.js+"/common/include/head.js?"+version).wait()
10 .script(LOCATION.js+"/common/include/foot.js?"+version).wait(function(){
11 //執行全局初始化,如異步登錄檢測等
12 loadFootReady();
13 });
14 </script>
7、在強交互的頁面,使用require.js來管理本頁面所用到的js,異步加載,通過初始化函數執行各種定時器啟動、事件綁定等。而初始化函數所需要的參數,
在jsp中預初始化,供js使用。
app.jsp中
1
<script type="text/javascript">
//需要用到的初始化參數
2 var initParams = {
3 maps:{
4 aIds:[]
5 },
6 aid: '${aid}',
7 bid: '${bid}',
8 cid: '${cid}'
9 };
10
11 <c:forEach items="${list}" var="obj" varStatus="sta">
12 <c:choose>
13 <c:when test="${obj.type==1}">
14 initParams.maps.aIds.push(obj.aId);
15 </c:when>
16 </c:choose>
17 </c:forEach>
18
19 //使用labjs繼續加載本頁面需要用到的js庫
20 $LAB.script(LOCATION.js+"/common/jquery.tmpl.js?"+version).wait()
21 .script(LOCATION.js+"/common/audio/jquery.jmp3.js?"+version).wait()
22 ;
23 </script>
24 <!--使用require.js加載這個應用的js-->
25 <script data-main="${staticJsRoot}/apps/view/main.js" src="${staticJsRoot}/common/require.js"></script>
8、接下來就是這個應用的js代碼重構了,充分利用requireJs良好的模塊管理機制,讓代碼結構更合理,維護更便利,可讀性更強。
main.js中
1 //首先定義好要用到的全局配置
2 requirejs.config({
3 baseUrl : LOCATION.app,
4 paths: {
5 "util": "utils/util",
6 "jsonUtil": "utils/jsonUtil",
7 "domUtil": "utils/domUtil",
8 "eventUtil": "utils/eventUtil",
9 "bUtil": "utils/bUtil",
10 "cUtil": "utils/cUtil",
11 "dUtil": "utils/dUtil",
12
13 "service": "service/service",
14 "aService": "service/aService",
15 "bService": "service/bService"
16 }
17 });
18
19 //然后加載應用的各種組件,并執行函數調用,run起來
20 requirejs(["config",
21 "service",
22 "util",
23 "template",
24 "loader",
25 "public"], function(config, service, util, tmpl){
26 window.MyApp = config;
27 MyApp.tmpl = tmpl;
28 //使用jsonUtil,將各種util combine成util.js,將各種service combine成service.js
29 util.combine(MyApp, service);
30 util.combine(MyApp, util);
31
32 MyApp.ready();
33 }
34 );
9、jsonUtil代碼:
1 define(function(){
2 return {
3 /*
4 * util包里的核心工具類
5 * 將json2中的key-value添加到json1中,
6 * 如果json2為空或未定義,則將json1添加到調用者中
7 * @author idu
8 */
9 combine: function(json1, json2){
10 if(!json2) {
11 var temp = json1;
12 json1 = this;
13 json2 = temp;
14 }
15
16 for(var i in json2){
17 json1[i+""] = json2[i];
18 }
19
20 return json1;
21 }
22 };
23 });
24
小結:當然重構并不是三言兩句就能說清楚了,不過這一步走過來后,現在無論前端性能,還是代碼質量、管理,都有了質的提升!