var html = "<table id='" + theId + "' border='0'>"; html += "<tr><td>" + title + "</td></tr>"; // ... $('theDiv').innerHTML = html;
另一種則是以 document.createElement(..) 的方式以 OO 的方式來建立所需的 html elemet:
var container= document.createElement('div'); container.style.position = "absolute"; container.className = "portal-container"; container.style.fontSize = 12; ... document.body.appendChild(container); ...
當然我們也常會混著一起使用,但這兩種方法都有一樣的缺點,就是日後維護會很辛苦,而且擴充的彈性很小,如果你開發的是一個 frmework 或可共用的 UI component,其他的開發人員想客製或擴充都會很痛苦,最主要的原因就是我們將太多 UI 的 html code 混雜到 script code 中了,想想看在 server side 的開發經驗中,我們是怎麼處理這種問題的?
將 model 和 view 分開,沒錯就是這個概念,這裡介紹一個 JavaScript templates engine,它可以有效的解決這個問題,看一個例子:
<html> <head> <script language="javascript" xsrc="trimpath/template.js"></script> ... </head> <textarea id="cart.jst" style="display:none;"> <table id='${tableId}' border='0'> <tr> <td> Hello ${customer.first} ${customer.last}.<br/> Your shopping cart has ${itemCount} item(s): </td> </tr> </table> </textarea> </html>
上面我們將 template.js include 進來,以便在 script 中使用,再來定義了一個 id 為 cart.jst 的 textarea,注意我們將它的 CSS 屬性 display 設定為 none,裡面則是標準 html code 加上 templates engine 能辨識的變數名稱。在 script 中我們可以這麼使用:
var model = { tableId : totalTableId++, customer : getCustomerById(id), itemCount : itemCount } $('theDiv').innerHTML = TrimPath.processDOMTemplate("cart.jst", model);
這裡我們將要丟入 templates engine 中的資料作組合,然後使用 TrimPath.processDOMTemplate("template id", 資料) 的方式讓 templates engine 幫我們作『融合』產出我們要的 html code。
就像是 FreeMarker,Velocity,Smarty 這些 Templates engine 一樣,TrimPath JavaScript templates engine 也提供了 if,for each,macro 等功能,值得多加使用讓 script 的維護不再是惡夢。