Skip to content

2026-07-08

/ 11 分鐘閱讀

/ You Might Not Need a Framework

HTML Templates:在 DOM 中定義惰性的 HTML 片段

上一篇介紹了 Web Components 的三個組成標準,以及 Custom Elements 的定義方式與生命週期。這篇進入第二個標準:HTML Templates,說明它如何讓你在 HTML 檔案中定義元件的結構,以及使用時需要注意的 CSS 作用範圍問題。

什麼是 template 元素?

<template> 是一個特殊的 HTML 標籤,瀏覽器會完全忽略它的內容:不解析、不渲染、不執行任何 CSS 或 JavaScript。它只是一段「備而不用」的 HTML 標記,等待 JavaScript 在需要的時候把它克隆出來使用。

html
<template id="template1">
  <header>
    <h1>This is a template</h1>
    <p>This content is not rendered initially</p>
  </header>
</template>

在有 <template> 之前,開發者常用一個取巧的方式:把 HTML 內容塞進 <script> 標籤,並設定一個瀏覽器不認識的 typelanguage 值,讓瀏覽器忽略它,再用 DOM API 和字串處理方法(例如 JSON.parse)取出內容。現在 <template> 提供了一個正式、乾淨的替代方案。

從概念上看,<template> 和 Document Fragment 有些相似,兩者都是在記憶體中建立一個不影響真實 DOM 的結構,某種程度上類似「虛擬 DOM」的概念。

如何在 Custom Element 中使用 template

<template> 的典型使用方式是在 Custom Element 的 connectedCallback 中克隆它的內容並附加到元件本身:

javascript
connectedCallback() {
  const template = document.getElementById("template1");
  const content = template.content.cloneNode(true);
  this.appendChild(content);
}

幾個重點:

  • getElementByIdquerySelector 取得 template 元素
  • 必須存取 template.content 才能取得模板的內容(DocumentFragment),而不是 template 元素本身
  • cloneNode(true)true 參數表示深度克隆,會一併複製所有子節點
  • 附加的是克隆的內容,不是原始 template,因為 template 是唯讀的,應該可以被重複克隆使用

注意:CSS 樣式的作用範圍問題

這是使用 <template> 時一個重要的陷阱。

如果在 template 內部定義 <style>,這些樣式不會被限制在元件範圍內,而是會套用到整個頁面:

html
<template id="template1">
  <style>
    /* 這個宣告會影響頁面上所有的 h1,不只是這個元件內的 */
    h1 { color: red }
  </style>
  <header>
    <h1>This is a template</h1>
  </header>
</template>

這是因為預設情況下,Custom Element 的節點是整個頁面 DOM 的一部分,沒有任何隔離機制。克隆進來的 <style> 標籤會成為文件的一部分,其中的 CSS 規則會影響頁面上所有符合選擇器的元素。

這個問題的解決方案就是下一個標準:Shadow DOM,它提供了真正的 CSS 作用範圍隔離。

複習

HTML 中的 template 元素是什麼?

template 元素是一段可以在執行時克隆並插入文件的標記片段,包含可以被動態渲染與修改的可重用 HTML 內容。瀏覽器預設會忽略其內容,不會對它進行渲染。

如何在 Custom Element 中克隆一個 template?

通常在 connectedCallback 方法中進行,使用 getElementById 或 querySelector 取得 template 元素,然後呼叫 content.cloneNode() 並將克隆的內容(而非 template 本身)附加到元件中。

在 template 內部定義樣式有什麼潛在問題?

預設情況下,在 template 內定義的樣式會套用到整個文件,而不僅限於 template 的內容。例如,將 h1 設為紅色的樣式宣告,會影響頁面上所有的 h1 元素,而不只是 template 內的那個。

template 元素和 Document Fragment 有什麼相似之處?

兩者都可以在記憶體中建立一個不影響真實 DOM 的結構,允許在不直接修改頁面 DOM 的情況下操作內容,本質上類似虛擬 DOM。

在有 template 元素之前,開發者常用什麼取巧的方式來處理 HTML 內容?

開發者會使用帶有瀏覽器不認識的 typelanguage 屬性的 <script> 標籤讓瀏覽器忽略其內容,再透過 DOM API(例如讀取 innerHTML)取出內容,並視需要用 JSON.parse 等方法處理。

小測驗

HTML template 元素的主要特性是什麼? 瀏覽器會完全忽略其內容,不進行解析或渲染
在 Web Component 中,通常如何克隆 template 的內容? 在 connectedCallback 方法中使用 content.cloneNode() 進行克隆
在 template 元素內定義樣式有什麼潛在問題? template 內的樣式可能會影響整個文件,而不只限於 template 內部
在建立記憶體中的 DOM 方面,什麼和 template 元素類似? Document Fragment
通常用哪個方法來存取 template 元素? document.querySelector()

此文章是 FrontendMasters 上的 Vanilla JS: You Might Not Need a Framework 課程筆記

最後更新時間:

Buy Me A Coffee

系列章節 第 18 篇 / 共 31 篇

0 %
MIT Licensed | Copyright © 2025-present Wen-Hsiu's Blog
Photo by Federica Galli on Unsplash