Javascript 模板元素

2023-02-17 10:58 更新

內(nèi)建的 ?<template>? 元素用來存儲 HTML 模板。瀏覽器將忽略它的內(nèi)容,僅檢查語法的有效性,但是我們可以在 JavaScript 中訪問和使用它來創(chuàng)建其他元素。

從理論上講,我們可以在 HTML 中的任何位置創(chuàng)建不可見元素來儲存 HTML 模板。那 <template> 元素有什么優(yōu)勢?

首先,其內(nèi)容可以是任何有效的HTML,即使它通常需要特定的封閉標簽。

例如,我們可以在其中放置一行表格 <tr> :

<template>
  <tr>
    <td>Contents</td>
  </tr>
</template>

通常,如果我們在 <tr> 內(nèi)放置類似 <div> 的元素,瀏覽器會檢測到無效的 DOM 結(jié)構(gòu)并對其進行“修復”,然后用 <table> 封閉 <tr> ,那不是我們想要的。而 <template> 則完全保留我們儲存的內(nèi)容。

我們也可以將樣式和腳本放入 <template> 元素中:

<template>
  <style>
    p { font-weight: bold; }
  </style>
  <script>
    alert("Hello");
  </script>
</template>

瀏覽器認為 <template> 的內(nèi)容“不在文檔中”:樣式不會被應用,腳本也不會被執(zhí)行, <video autoplay> 也不會運行,等。

當我們將內(nèi)容插入文檔時,該內(nèi)容將變?yōu)榛顒訝顟B(tài)(應用樣式,運行腳本等)。

插入模板

模板的 content 屬性可看作DocumentFragment —— 一種特殊的 DOM 節(jié)點。

我們可以將其視為普通的DOM節(jié)點,除了它有一個特殊屬性:將其插入某個位置時,會被插入的則是其子節(jié)點。

例如:

<template id="tmpl">
  <script>
    alert("Hello");
  </script>
  <div class="message">Hello, world!</div>
</template>

<script>
  let elem = document.createElement('div');

  // Clone the template content to reuse it multiple times
  elem.append(tmpl.content.cloneNode(true));

  document.body.append(elem);
  // Now the script from <template> runs
</script>

讓我們用 <template> 重寫上一章的 Shadow DOM 示例:

<template id="tmpl">
  <style> p { font-weight: bold; } </style>
  <p id="message"></p>
</template>

<div id="elem">Click me</div>

<script>
  elem.onclick = function() {
    elem.attachShadow({mode: 'open'});

    elem.shadowRoot.append(tmpl.content.cloneNode(true)); // (*)

    elem.shadowRoot.getElementById('message').innerHTML = "Hello from the shadows!";
  };
</script>

在 (*) 行,我們將 tmpl.content 作為 DocumentFragment 克隆和插入,它的子節(jié)點(<style>,<p>)將代為插入。

它們會變成一個 Shadow DOM:

<div id="elem">
  #shadow-root
    <style> p { font-weight: bold; } </style>
    <p id="message"></p>
</div>

總結(jié)

總結(jié)一下:

  • ?<template>? 的內(nèi)容可以是任何語法正確的 HTML。
  • ?<template>? 內(nèi)容被視為“超出文檔范圍”,因此它不會產(chǎn)生任何影響。
  • 我們可以在JavaScript 中訪問 ?template.content? ,將其克隆以在新組件中重復使用。

<template> 標簽非常獨特,因為:

  • 瀏覽器將檢查其中的HTML語法(與在腳本中使用模板字符串不同)。
  • 但允許使用任何頂級 HTML 標簽,即使沒有適當包裝元素的無意義的元素(例如 ?<tr>? )。
  • 其內(nèi)容是交互式的:插入其文檔后,腳本會運行, ?<video autoplay>? 會自動播放。

<template> 元素不具有任何迭代機制,數(shù)據(jù)綁定或變量替換的功能,但我們可以在其基礎(chǔ)上實現(xiàn)這些功能。


以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號