在 Twitter 上根据Manuel Matuzović 最近的一篇文章进行了热烈的讨论之后,我认为值得在这里写一些简短的想法。今天,我们快速浏览一下该<template>元素以及它如何派上用场。

所以简单来说,<template>HTML元素就是用来存放还没有被使用的HTML的。元素本身及其所有内容都是不可见的,因此它基本上可以出现在文档中的任何位置而没有太大风险。尽管您通常会在根级别拥有模板。

做什么的

<template>让我们从不允许您做任何否则不可能做的事情开始。这样,它实际上更像是一种便利工具。如果您有重要的 HTML 结构需要在运行时注入,使用document.createElement和手动注入可能会非常麻烦element.setAttribute

Manuel 的例子中,他使用一个模板来保存一个按钮,当 JavaScript 最终可用时需要注入该按钮,因为在那之前它是行不通的。使用 SVG 在 JS 中手动创建该按钮,所有这些都非常麻烦。将 HTML 移动到 JS 逻辑中也会违反适当的关注点分离。

<template id="burger-template">
  <button type="button" aria-expanded="false" aria-label="Menu" aria-controls="mainnav">
    <svg width="24" height="24" aria-hidden="true">
      <path d="M3 18h18v-2H3v2zm0-5h18v-2H3v2zm0-7v2h18V6H3z">
    </svg>
  </button>
</template>

如何使用它

一旦你<template>的 HTML 中有了一个元素,你就可以在 JavaScript 中访问它并克隆它以在你想要的任何地方呈现它。

const template = document.querySelector('#id-of-template')
const content = template.content.cloneNode(true)

container.append(content)

它也不限于单次使用。您可以根据需要创建任意数量的克隆。MDN页面有一个很好的示例,可以在模板中存储表行,因此您可以轻松地按需克隆和添加新行。

例如,Sass Guidelines 使用模板注入链接以直接在 GitHub 上编辑视图或编辑每一章。在理想情况下,这些链接会一直存在,但因为 Sass-Guidelines 是从普通的 Markdown 文件构建的,所以这些链接是在 JS 中生成的。这是实现模板的拉取请求

浏览器支持

浏览器支持出奇的好。当前几乎 98% 的景观都支持它,所以请尽情发挥吧。如果你必须支持老代理,你可以像这样测试支持:

if ('content' in document.createElement('template')) {
  // `<template>` is supported.
}

为什么不是隐藏元素?

<div>在这篇文章之后,有些人问使用隐藏的 DOM 元素(例如 a来保存我们的模板内容)有什么不同。毕竟,感觉相似?

<!-- Don’t do that, it’s just not as good or safe. -->
<div id="template" style="display: none;">
  <!-- Template content here -->
</div>

<template>使用 a更好的原因有几个——有些比其他的更好(感谢 Spankalee概述了一些我没有想到的)——所以选择对你来说最有说服力的:

  • 与隐藏容器中的内容不同,a 的内容<template>惰性的:不加载图像和脚本、不应用样式、不查询元素等。
  • 内容模型验证已关闭;a<template>可以安全地包含 a <td><li>或者<dd>没有验证者抱怨。同样,a 几乎<template>可以在任何地方呈现,而 a 可能并非如此<div>
  • CSS 可能会失败、被禁用或自定义,因此使用 CSS 声明来隐藏 a<div>并不是真正的防弹。另一方面,<template>即使没有 CSS,该元素也有可能始终被隐藏。如果您走那条路, HTMLhidden属性可能是更好的选择。
  • 搜索引擎可能会索引隐藏在 CSS 中的内容。或者可能不是。目前还不清楚,因为他们的索引算法是出了名的不透明。您可能不希望索引无意义的模板数据。
  • <template>如果你问我,它只是更语义化和更明显的意图,一个隐藏的容器,这可能与第三方工具、扩展等特别相关。

包起来

长话短说,模板有助于避免手动创建复杂的 DOM 结构。对于单个节点,使用内置的操作方法很好,但对于任何更复杂的情况,您可能希望按原样存储 HTML blob,并在需要时克隆并填充它。

一如既往,我希望它有所帮助!

HTML 中的模板