0Pricing
HTML Academy · 课时

template 元素:惰性内容

定义经过解析但在激活前不会渲染的 HTML

template 元素:惰性内容 是 CoddyKit 上的免费 HTML Academy 课时。 这是第 1 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 HTML Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 HTML Academy 课程共包含 4 节课。

什么是 template 元素

<template> 元素包含已解析但不会渲染的 HTML:

  • 内容位于 DOM 中,但不会显示
  • 其中的脚本不会执行
  • 图像不会加载
  • CSS 不会应用
  • 在克隆之前它处于“惰性”状态

template 基础用法

定义一个 template 并检查其内容:

<template id="card-template">
  <div class="card">
    <h2 class="card-title"></h2>
    <p class="card-body"></p>
    <a class="card-link">Learn more</a>
  </div>
</template>

<script>
const tmpl = document.getElementById('card-template');
console.log(tmpl.content); // DocumentFragment
console.log(tmpl.content.querySelector('.card')); // The div node
// Not rendered on the page yet
</script>

template.content

.content 属性返回一个 DocumentFragment:

const template = document.querySelector('#card-template');
const fragment = template.content;

// fragment is a DocumentFragment — a lightweight DOM container
// It is not attached to the document
// Modifying fragment does NOT affect the original template
// You must clone it before using it

克隆 template

使用 cloneNode(true) 创建 template 内容的副本:

const tmpl = document.getElementById('card-template');
const clone = tmpl.content.cloneNode(true);  // true = deep clone

// Modify the clone:
clone.querySelector('.card-title').textContent = 'HTML5 Guide';
clone.querySelector('.card-body').textContent = 'Learn HTML5 from scratch.';
clone.querySelector('.card-link').href = '/html5';

// Add to the page:
document.getElementById('card-list').appendChild(clone);

从 template 渲染列表

从一个 template 生成多个项目:

<ul id="users"></ul>

<template id="user-tmpl">
  <li class="user">
    <strong class="user-name"></strong>
    <span class="user-role"></span>
  </li>
</template>

<script>
const tmpl = document.getElementById('user-tmpl');
const list = document.getElementById('users');

const users = [
  { name: 'Alice', role: 'Admin' },
  { name: 'Bob', role: 'Editor' },
];

users.forEach(user => {
  const clone = tmpl.content.cloneNode(true);
  clone.querySelector('.user-name').textContent = user.name;
  clone.querySelector('.user-role').textContent = user.role;
  list.appendChild(clone);
});
</script>

为什么使用 template 而不是 innerHTML

template 比 innerHTML 更安全、更高效:

// innerHTML approach (less safe):
container.innerHTML = `<div>${userProvidedContent}</div>`;
// Risk: XSS if userProvidedContent is not sanitized

// template approach (safer):
const clone = tmpl.content.cloneNode(true);
clone.querySelector('.name').textContent = userProvidedContent;
// textContent sets text only — HTML tags are not parsed
// No XSS risk

包含嵌套数据的 template

包含嵌套结构的复杂 template:

<template id="post-tmpl">
  <article>
    <header>
      <h2 class="title"></h2>
      <time class="date" datetime=""></time>
    </header>
    <p class="excerpt"></p>
    <a class="read-more">Read more</a>
  </article>
</template>

<script>
function renderPost(post) {
  const clone = document.getElementById('post-tmpl').content.cloneNode(true);
  clone.querySelector('.title').textContent = post.title;
  clone.querySelector('.date').textContent = post.date;
  clone.querySelector('.date').dateTime = post.isoDate;
  clone.querySelector('.excerpt').textContent = post.excerpt;
  clone.querySelector('.read-more').href = post.url;
  return clone;
}
</script>

template 不会渲染

验证 template 内容对用户不可见:

<template id="hidden-tmpl">
  <script>alert('This runs when cloned, not when defined');</script>
  <img src="wont-load-yet.jpg" alt="Won't load until cloned">
</template>
<!-- The script and image are NOT activated until you clone and append the template -->
<!-- This makes templates safe for defining content without side effects -->

template 与 script type=text/html

传统模式与现代 template:

<!-- Old pattern (script hack): -->
<script type="text/html" id="old-tmpl">
  <div class="card">...</div>
</script>
<script>
const html = document.getElementById('old-tmpl').innerHTML;
container.innerHTML = html;  // XSS risk!
</script>

<!-- Modern template: -->
<template id="card-tmpl">...</template>
<!-- Safer, semantic, no XSS risk -->

组件库中的 template

原生组件库中的 template 模式:

class UserCard extends HTMLElement {
  connectedCallback() {
    const tmpl = document.getElementById('user-card-tmpl').content.cloneNode(true);
    tmpl.querySelector('.name').textContent = this.getAttribute('name');
    this.appendChild(tmpl);
  }
}

快速检查

cloneNode(true) 对 template 的 content 属性执行什么操作?

回顾:template 元素

template 的核心要点:

  • 惰性 HTML——已解析但不会渲染
  • template.content——返回一个 DocumentFragment
  • content.cloneNode(true)——创建深层副本,可直接修改和追加
  • 比 innerHTML 更安全——使用 textContent 不会通过 HTML 注入内容
  • 用于自定义元素、重复的界面模式和 Web Components

常见问题解答

「template 元素:惰性内容」课时是免费的吗?

是的 — 「template 元素:惰性内容」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 HTML Academy 课程的其余内容,请升级到 CoddyKit PRO。 HTML Academy 课程共包含 4 节课。

「template 元素:惰性内容」这节课中我会学到什么?

定义经过解析但在激活前不会渲染的 HTML 你通过在浏览器中直接运行的动手代码来练习 HTML Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 HTML Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 HTML Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 1 节课,共 4 节。

「template 元素:惰性内容」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 HTML Academy 课中编写并运行代码吗?

能。每节 HTML Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. template 元素:惰性内容
  2. 使用 cloneNode 克隆模板
  3. 将 template 用于 JavaScript 渲染
  4. 模板与 innerHTML 的安全性
← 返回 HTML Academy