Handlebar.js: http://handlebarsjs.com/
樣板引擎的一種,能將程式邏輯與樣板內容盡可能地分離。
LESS: http://lesscss.org/
CSS的變種,能以類似程式般地設計方式來規劃CSS,並轉譯成CSS來使用。
這裡以WOG的Foot頁面來做初步設計,檔案架構如下
- 代碼: 選擇全部
ROOT
- js
- libs
- handlebars-v3.0.3.js
- jquery-2.0.3.min.js
- compiled_template.js
- css
wog_foot.css
- less
- wog_foot.less
- template
- foot.hbs
開發時有用Grunt做handlebars與less的自動轉換,把hbs檔案轉換成compiled_template.js,LESS轉成相對應的css
Handlebars的相關程式碼 寫:template/foot.hbs
- 代碼: 選擇全部
<form action="wog_act.php" method="post" name="menu" target="mission">
<table class="menu-table">
<tr>
<td>
<table>
<tr><td class="header"><div id="con_fight">冒險旅程</div></td></tr>
<tr><td><input id="btnAdventure" type="button" value="冒險開始" name="ats1" onClick="parent.ad_view()" accesskey="a"></td></tr>
<tr><td><input id="btnStatus" type="button" value="角色狀態" onClick="parent.act_click(\'chara\',\'status_view\')" accesskey="s"></td></tr>
<tr><td><input id="btnChampion" type="button" value="冠軍狀態" onClick="parent.act_click(\'chara\',\'cp\')" accesskey="o"></td></tr>
</table>
</td>
<td>
<table>
<tr><td class="header">貿易交流</td></tr>
<tr><td><input id="btnStore" type="button" value="商店街" onClick="parent.select_store()" accesskey="c"></td></tr>
<tr><td><input id="btnArm" type="button" value="裝備欄" onClick="parent.arm_select(1)" accesskey="e"></td></tr>
<tr><td><input id="btnHotel" type="button" value="住 宿" onClick="parent.act_click(\'store\',\'hotel\')" accesskey="h"></td></tr>
</table>
</td>
<td>
<table>
<tr><td class="header">對象(<a href="javascript:parent.noname()"><font color="#000000">取消</font></a>)</td></tr>
<tr><td><input type="text" name="towho" size="4"></td></tr>
<tr><td><input id="btnTout" type="button" value="偵查對手" onClick="parent.act_click(\'chara\',\'view2\',document.menu.towho.value)" accesskey="v"></td></tr>
<tr><td><input id="btnDepot" type="button" value="銀行倉庫" onClick="parent.act_click(\'arm\',\'depot_list\')" accesskey="d"></td></tr>
</table>
</td>
<td>
<table>
<tr><td class="header">其他</td></tr>
<tr><td><input id="btnMission" type="button" value="任務手冊" onClick="parent.mission_ed()" accesskey="b"></td></tr>
<tr><td><input id="btnSkill" type="button" value="技能手冊" onClick="parent.act_click(\'skill\',\'view\')" accesskey="k"></td></tr>
<tr><td><input id="btnInfo" type="button" value="情報中心" onClick="parent.act_click(\'system\',\'view1\')" accesskey="q"></td></tr>
</table>
</td>
</tr>
</table>
</form>
{{#if viewCopyright}}
<table cellspacing="0" cellpadding="0" align="center">
<tr>
<td valign="top" align="center" >
<b><a href="http://www.et99.net/viewforum.php?f=36" target="_blank">WOG</a> V4 Copyright (C) <a href="http://www.et99.net" target="_blank">ETERNAL</a></b>
</td>
</tr>
</table>
{{/if}}
js/compiled_template.js
- 代碼: 選擇全部
this["template"] = this["template"] || {};
this["template"]["foot"] = Handlebars.template({"1":function(depth0,helpers,partials,data) {
return "<table cellspacing=\"0\" cellpadding=\"0\" align=\"center\">\r\n <tr>\r\n <td valign=\"top\" align=\"center\" >\r\n <b><a href=\"http://www.et99.net/viewforum.php?f=36\" target=\"_blank\">WOG</a> V4 Copyright (C) <a href=\"http://www.et99.net\" target=\"_blank\">ETERNAL</a></b>\r\n </td>\r\n </tr>\r\n</table>\r\n";
},"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) {
var stack1;
return "<form action=\"wog_act.php\" method=\"post\" name=\"menu\" target=\"mission\">\r\n <table class=\"menu-table\">\r\n <tr>\r\n <td>\r\n <table>\r\n <tr><td class=\"header\"><div id=\"con_fight\">冒險旅程</div></td></tr>\r\n <tr><td><input id=\"btnAdventure\" type=\"button\" value=\"冒險開始\" name=\"ats1\" onClick=\"parent.ad_view()\" accesskey=\"a\"></td></tr>\r\n <tr><td><input id=\"btnStatus\" type=\"button\" value=\"角色狀態\" onClick=\"parent.act_click(\\'chara\\',\\'status_view\\')\" accesskey=\"s\"></td></tr> \r\n <tr><td><input id=\"btnChampion\" type=\"button\" value=\"冠軍狀態\" onClick=\"parent.act_click(\\'chara\\',\\'cp\\')\" accesskey=\"o\"></td></tr>\r\n </table>\r\n </td>\r\n <td>\r\n <table>\r\n <tr><td class=\"header\">貿易交流</td></tr>\r\n <tr><td><input id=\"btnStore\" type=\"button\" value=\"商店街\" onClick=\"parent.select_store()\" accesskey=\"c\"></td></tr>\r\n <tr><td><input id=\"btnArm\" type=\"button\" value=\"裝備欄\" onClick=\"parent.arm_select(1)\" accesskey=\"e\"></td></tr> \r\n <tr><td><input id=\"btnHotel\" type=\"button\" value=\"住 宿\" onClick=\"parent.act_click(\\'store\\',\\'hotel\\')\" accesskey=\"h\"></td></tr>\r\n </table>\r\n </td>\r\n <td>\r\n <table>\r\n <tr><td class=\"header\">對象(<a href=\"javascript:parent.noname()\"><font color=\"#000000\">取消</font></a>)</td></tr>\r\n <tr><td><input type=\"text\" name=\"towho\" size=\"4\"></td></tr>\r\n <tr><td><input id=\"btnTout\" type=\"button\" value=\"偵查對手\" onClick=\"parent.act_click(\\'chara\\',\\'view2\\',document.menu.towho.value)\" accesskey=\"v\"></td></tr> \r\n <tr><td><input id=\"btnDepot\" type=\"button\" value=\"銀行倉庫\" onClick=\"parent.act_click(\\'arm\\',\\'depot_list\\')\" accesskey=\"d\"></td></tr>\r\n </table>\r\n </td>\r\n <td>\r\n <table>\r\n <tr><td class=\"header\">其他</td></tr>\r\n <tr><td><input id=\"btnMission\" type=\"button\" value=\"任務手冊\" onClick=\"parent.mission_ed()\" accesskey=\"b\"></td></tr>\r\n <tr><td><input id=\"btnSkill\" type=\"button\" value=\"技能手冊\" onClick=\"parent.act_click(\\'skill\\',\\'view\\')\" accesskey=\"k\"></td></tr> \r\n <tr><td><input id=\"btnInfo\" type=\"button\" value=\"情報中心\" onClick=\"parent.act_click(\\'system\\',\\'view1\\')\" accesskey=\"q\"></td></tr>\r\n </table>\r\n </td>\r\n </tr>\r\n </table>\r\n</form>\r\n"
+ ((stack1 = helpers['if'].call(depth0,(depth0 != null ? depth0.viewCopyright : depth0),{"name":"if","hash":{},"fn":this.program(1, data, 0),"inverse":this.noop,"data":data})) != null ? stack1 : "");
},"useData":true});
wog_foot.less的相關程式碼 寫:less/wog_foot.less
- 代碼: 選擇全部
.menu-table {
width: 300px;
border: 0px;
border-spacing: 0;
background-color: #2B4686;
td {
vertical-align: top;
}
.header {
background-color: #CFD2DC;
color: #000000;
height: 22px;
text-align: center;
}
#con_fight { color: #000000;}
input[name="towho"] {
line-height: 1.6em;
width: 6em;
}
button {
line-height: 1em;
}
}
css/wog_foot.css
- 代碼: 選擇全部
.menu-table {
width: 300px;
border: 0px;
border-spacing: 0;
background-color: #2B4686;
}
.menu-table td {
vertical-align: top;
}
.menu-table .header {
background-color: #CFD2DC;
color: #000000;
height: 22px;
text-align: center;
}
.menu-table #con_fight {
color: #000000;
}
.menu-table input[name="towho"] {
line-height: 1.6em;
width: 6em;
}
.menu-table button {
line-height: 1em;
}
wog_foot.htm的<head>內加入這行link標籤
- 代碼: 選擇全部
<link type="text/css" rel="stylesheet" href="css/wog_foot.css"/>
index.htm的<head>內加入這行<script>標籤
- 代碼: 選擇全部
<script language="javascript" src="js/libs/handlebars-v3.0.3.js"></script>
<script language="javascript" src="js/compiled_template.js"></script>
js/wog_tool.js的foot_fire() function改寫成以下內容
- 代碼: 選擇全部
function foot_fire()
{
w_m(template.foot({viewCopyright: UI.set_frame!=1}));
var a=Gookie("wog_setui");
setUI(parseInt(a));
switch (UI.set_frame)
{
case 1:
dfoot=f;
p_m();
UI.set_target=f;
break;
case 2:
dfoot=parent.foot.document;
p_m();
UI.set_target=dfoot;
break;
default:
setUI(1);
dfoot=parent.foot.document;
p_m();
UI.set_target=dfoot;
break;
}
Drag.init(f.getElementById("wog_menu"));
};
可以改進的部分還很多,但經過了初步的改寫後,可以看到Foot樣板中的程式邏輯已相當程度地從中分離了,不管是foot.hbs還是foot_fire()內的程式碼與原先相比都較容易維護,而顯示結果與原來的內容相比並無二致。
在LESS部分,將樣式設計的內容自樣板中抽離改放到LESS內,並利用block的概念來規劃樣式表,能讓樣板顯得較為簡潔而且也容易維護LESS。
其他還有很多工具能用,但多次測試後這兩件工具對於已有一定規模的WOG來說要改寫起來比較沒有挫折感,在程式邏輯部分的更動也不太多,可接受度應該不低。
![Laughing :lol:](http://www.et99.net/images/smilies/icon_lol.gif)