JavaScript >> Javascript 文檔 >  >> JavaScript

使用 JavaScript 進行簡單、可維護的模板

我的可維護 JavaScript 原則之一是將 HTML 排除在 JavaScript 之外。這個原則背後的想法是所有標記都應該放在一個地方。當您只有一個地方可以檢查時,調試標記問題會容易得多。當我看到這樣的代碼時,我總是畏縮:

function addItem(list, id, text){
    var item = document.createElement("li");
    item.innerHTML = "<a href=\"/view/" + id + "\">" + text + "</a>";  //ick
    item.id = "item" + id;
    list.appendChild(item);
}

每當我看到像這樣嵌入到 JavaScript 中的 HTML 時,我就預見到有一段時間會出現標記問題,而且它需要的時間遠遠超過它應該追踪的時間,因為當真正的問題出在 JavaScript 中時,您正在檢查模板。

如今,有一些非常出色的模板系統可以在瀏覽器和服務器上運行,例如 Mustache 和 Handlebars。這樣的模板系統允許所有標記存在於相同的模板文件中,同時支持在客戶端或服務器上或兩者上呈現。這在設置和準備時間上會有一點開銷,但最終的結果是一個更易於維護的系統。

但是,有時更改為全新的模板系統是不可能或不值得的。在這些情況下,我喜歡將模板嵌入到實際的 HTML 本身中。如何在不向可能使用或不使用的頁面添加垃圾標記的情況下做到這一點?我使用了 HTML 中一個熟悉但被低估的部分:註釋。

許多開發人員不知道評論實際上是 DOM 的一部分。每個評論都表示為 DOM 中的一個節點,並且可以像任何其他節點一樣進行操作。您可以使用 nodeValue 獲取任何評論的文本 財產。例如,考慮一個簡單的頁面:

<!DOCTYPE html>
<html>
    <body><!--Hello world!--></body>
</html>

您可以通過以下方式獲取評論中的文本:

var commentText = document.body.firstChild.nodeValue;

commentText 的值 很簡單,“世界你好!”。所以 DOM 很友好地移除了開始和結束註釋指示符。再加上註釋在標記中完全無害這一事實,使它們成為放置簡單模板字符串的理想位置。

考慮一個動態列表,您可以在其中添加新項目並且 UI 會立即更新。在這種情況下,我喜歡將模板註釋作為 <ul> 的第一個孩子 或 <ol> 所以它的位置不受其他變化的影響:

<ul id="mylist"><!--<li id="item%s"><a href="/item/%s">%s</a></li>-->
    <li id="item1"><a href="/item/1">First item</a></li>
    <li id="item2"><a href="/item/2">Second item</a></li>
    <li id="item3"><a href="/item/3">Third item</a></li>
</ul>

當我需要向列表中添加另一個項目時,我只需從註釋中獲取模板並使用非常簡單的 sprintf() 對其進行格式化 實現:

/*
 * This function does not attempt to implement all of sprintf, just %s,
 * which is the only one that I ever use.
 */
function sprintf(text){
    var i=1, args=arguments;
    return text.replace(/%s/g, function(pattern){
        return (i < args.length) ? args[i++] : "";
    });
}</code>

這是一個非常小的 sprintf() 僅支持使用 %s 的實現 更換。在實踐中,這是我唯一使用過的,所以我不會為更複雜的處理而煩惱。您可能希望使用不同的格式或函數來進行替換——這實際上只是一個偏好問題。

有了這個,我就剩下了一個相當簡單的添加新項目的方法:

function addItem(list, id, text){
    var template = list.firstChild.nodeValue,
        result = sprintf(template, id, id, text),
        div = document.createElement("div");

    div.innerHTML = result;
    list.appendChild(div.firstChild);
}

此函數檢索模板文本並將其格式化為 result .然後,一個新的 <div> 被創建為新 DOM 元素的容器。 result 被注入到 <div> ,它會創建 DOM 元素,然後將結果添加到列表中。

使用這種技術,您的標記仍然存在於完全相同的位置,無論是 PHP 文件還是 Java servlet。最重要的是 HTML 沒有嵌入到 JavaScript 中。

如果它不太適合您,也有一些非常簡單的方法可以增強此解決方案:

  • 如果您使用的是 YUI,您可能需要使用 Y.substitute() 而不是 sprintf() 功能。
  • 您可能希望將模板放入 <script> 帶有 type 自定義值的標記 (類似於把手)。您可以使用 text 檢索模板文本 財產。

當然,這是一個非常簡單的例子。如果您需要條件和循環等更複雜的功能,您可能需要使用完整的模板解決方案。


Tutorial JavaScript 教程
  1. 使用 WebRTC、Websocket、PHP +JS 從頭開始構建視頻會議應用程序 第 23 天

  2. 使用 Git Hooks 設置 React 以在推送代碼之前自動測試和 Lint

  3. react-router:設置教程

  4. 加載類似但新的數組時如何保留數組引用?

  5. JS ES6 對象解構

  6. 在 React 中構建地址搜索組件

  7. 你需要一個 JavaScript 初學者工具包

  1. 📦 webpack 的秘密

  2. jQuery 獲取今天的日期 dd/mm/yyyy

  3. 關於模板引擎的真相第 2 部分

  4. 用onclick事件調用php函數?

  5. 在 JavaScript 中將數組轉換為地圖

  6. 我為開始使用 ReactJS 而構建的 5 個項目

  7. 在 JavaScript 和 PHP 中正確使用 JSON

  1. Serverless,Durable 函數,如何學習實現 Fan-out/fan-in 模式

  2. 使用 JEST 在 Javascript 中編寫單元測試

  3. 如何使用 HTML、CSS 和 JavaScript 構建引人入勝的演示文稿

  4. 是的,這裡有 4 種使用 Vue 處理 SEO 的方法(即使沒有 Node SSR)