[译] 编写可以复用的 HTML 模板

简介: 在本文以及接下来的三篇文章中,我们将这些技术应用到测试并更详细地去验证它们,看下我们在如今的产品如何应用它们。

[译] 编写可以复用的 HTML 模板
原文地址:Crafting Reusable HTML Templates
原文作者:Caleb Williams
译文出自:掘金翻译计划
本文永久链接:github.com/xitu/gold-m…
译者:Mirosalva
校对者:xionglong58,HearFishle


在我们的上一篇文章中, 我们讨论了 web 组件规范(自定义元素、shadow DOM 和 HTML 模板)的高级特性。在本文以及接下来的三篇文章中,我们将这些技术应用到测试并更详细地去验证它们,看下我们在如今的产品如何应用它们。为了做到这些,我们将会从零开始构建一个自定义模式的对话框,来查看这些不同的技术如何组装在一起。

系列文章:

Web 组件简介
编写可以复用的 HTML 模板 (本文)
从 0 开始创建自定义元素
使用 Shadow DOM 封装样式和结构
Web 组件的高阶工具
HTML 模板
Web 组件规范中最不被认可但是最强大的功能之一是 <模板> 元素。在这个系列的第一篇文章中,我们将这种模板元素定义为『仅在调用时才渲染的用户自定义 HTML 模板』。换句话说,模板就是一种当浏览器被告知时才执行的 HTML 代码,其他情况下是被忽略的。

这种模块可以通过许多有趣的方式去传递和应用。基于本文的目的,我们将看下如何为一种最终应用到自定义元素中的对话框创建模板。

定义你的模板

就像它听起来这样简单,一个 是一种 HTML 元素,所以一个含内容的模板所具备的最基本形式如下:

<template>
  <h1>Hello world</h1>
</template>

在浏览器中运行这段代码会显示空白页面,因为浏览器并没有渲染模板元素内容。这种方式的强大之处在于它允许我们保存自定义内容(或内容结构),以供后续使用,而不需要使用 JavaScript 来动态编写 HTML 代码。

为了使用模板,我们 将 需要用到 JavaScript。

const template = document.querySelector('template');
const node = document.importNode(template.content, true);
document.body.appendChild(node);

真正神奇的地方在于 document.importNode 方法。这个函数将会为模板的 内容 创建一份副本,并且做好将拷贝插入其他文档(或文档片段)的准备。函数的第一个参数获取到模板的内容,第二个参数告诉浏览器要对元素的 DOM 子树做一份深度拷贝(也就是拷贝它的所有子节点)。

我们可以直接使用 template.content,但是这样做的话,我们随后需要把内容从元素中移除并将它拼接到其他文档的 body 部分。任何 DOM 节点仅可以被接入到一个位置,所以随后对模板内容的使用将会导致空文档片段(基本上是一个空值),因为之前已移动了内容对象。使用 document.importNode 允许我们在不同的位置来复用同一个模板内容的实例。

以上代码执行后,节点内容会被拼接到 document.body 对象,并被渲染显示给用户。这样最终使我们能够做许多有趣的事情,比如为我们的用户(或者我们程序的消费者)提供创建内容的模板,类似下面的 demo,在第一篇文章我们讨论过:

请参阅笔记模板样例,来自 CodePen 的 Caleb Williams (@calebdwilliams)。

这个例子中,我们提供了两个模板来渲染同样的内容 —— 作者和他写的书。当表格变化时,我们选择渲染与该变化值相关联的模板。使用相同的技术允许我们最终创建一个自定义元素,该元素将使用稍后定义的模板。

模板的多功能性

模板中一个有趣的点是我们可以包含 任意 HTML,包括脚本和样式元素。一个非常简单的模板例子是添加一个可以提示被点击的按钮。

<button id="click-me">Log click event</button>

让我们加点样式:

button {
  all: unset;
  background: tomato;
  border: 0;
  border-radius: 4px;
  color: white;
  font-family: Helvetica;
  font-size: 1.5rem;
  padding: .5rem 1rem;
}

...然后通过一个非常简单的脚本来调用按钮:

const button = document.getElementById('click-me');
button.addEventListener('click', event => alert(event));

当然,我们可以直接使用

<template id="template">
  <script>
    const button = document.getElementById('click-me');
    button.addEventListener('click', event => alert(event));
  </script>
  <style>
    #click-me {
      all: unset;
      background: tomato;
      border: 0;
      border-radius: 4px;
      color: white;
      font-family: Helvetica;
      font-size: 1.5rem;
      padding: .5rem 1rem;
    }
  </style>
  <button id="click-me">Log click event</button>
</template>

一旦这个元素被加入到 DOM 结构中,我们会看到一个 ID 为 #click-me 的新按钮,一个全局的 CSS selector 被绑定到这个按钮的 ID,一个简单的事件监听回调函数会提示元素的点击事件。

至于我们的脚本,我们仅需使用 document.importNode 来拼接内容,并且我们有一个包含大致内容的 HTML 模板,在页与页之间可以复用。

请参阅笔记包含脚本和样式的模板例子,来自 CodePen 的 Caleb Williams (@calebdwilliams)。

为我们的对话框编写模板

回到我们编写一个对话框元素这个任务,我们希望定义自己的模板内容和样式。

<template id="one-dialog">
  <script>
    document.getElementById('launch-dialog').addEventListener('click', () => {
      const wrapper = document.querySelector('.wrapper');
      const closeButton = document.querySelector('button.close');
      const wasFocused = document.activeElement;
      wrapper.classList.add('open');
      closeButton.focus();
      closeButton.addEventListener('click', () => {
        wrapper.classList.remove('open');
        wasFocused.focus();
      });
    });
  </script>
  <style>
    .wrapper {
      opacity: 0;
      transition: visibility 0s, opacity 0.25s ease-in;
    }
    .wrapper:not(.open) {
      visibility: hidden;
    }
    .wrapper.open {
      align-items: center;
      display: flex;
      justify-content: center;
      height: 100vh;
      position: fixed;
        top: 0;
        left: 0;
        right: 0;
        bottom: 0;
      opacity: 1;
      visibility: visible;
    }
    .overlay {
      background: rgba(0, 0, 0, 0.8);
      height: 100%;
      position: fixed;
        top: 0;
        right: 0;
        bottom: 0;
        left: 0;
      width: 100%;
    }
    .dialog {
      background: #ffffff;
      max-width: 600px;
      padding: 1rem;
      position: fixed;
    }
    button {
      all: unset;
      cursor: pointer;
      font-size: 1.25rem;
      position: absolute;
        top: 1rem;
        right: 1rem;
    }
    button:focus {
      border: 2px solid blue;
    }
  </style>
  <div class="wrapper">
  <div class="overlay"></div>
    <div class="dialog" role="dialog" aria-labelledby="title" aria-describedby="content">
      <button class="close" aria-label="Close">&#x2716;&#xfe0f;</button>
      <h1 id="title">Hello world</h1>
      <div id="content" class="content">
        <p>This is content in the body of our modal</p>
      </div>
    </div>
  </div>
</template>

这段代码将成为我们对话框的基础部分。简单介绍一下,我们有一个全局的关闭按钮,一个标题和一些内容。我们也添加了一些行为来实现可视化触发对话框(尽管它还无法被访问)。不幸的是,样式和脚本内容并非仅限作用于我们的模板,而是应用于整个文件,当我们将多个模板实例添加到 DOM 时,并没有产生理想的中的效果。在下篇文章中,我们将应用自定义元素f生成方法并创建我们自己的元素,实时使用该模板并封装元素的行为。

请查阅笔记以脚本模板来编写对话框 ,来自 CodePen 的 Caleb Williams (@calebdwilliams)。

目录
相关文章
|
17天前
|
安全 Go
Golang深入浅出之-Go语言模板(text/template):动态生成HTML
【4月更文挑战第24天】Go语言标准库中的`text/template`包用于动态生成HTML和文本,但不熟悉其用法可能导致错误。本文探讨了三个常见问题:1) 忽视模板执行错误,应确保正确处理错误;2) 忽视模板安全,应使用`html/template`包防止XSS攻击;3) 模板结构不合理,应合理组织模板以提高可维护性。理解并运用这些最佳实践,能提升Go语言模板编程的效率和安全性,助力构建稳健的Web应用。
22 0
|
2月前
|
Java
有关Java发送邮件信息(支持附件、html文件模板发送)
有关Java发送邮件信息(支持附件、html文件模板发送)
49 1
|
2月前
分享82个Html经典模板,总有一款适合您
分享82个Html经典模板,总有一款适合您
25 0
|
2月前
|
前端开发 安全
分享81个Html经典模板,总有一款适合您
分享81个Html经典模板,总有一款适合您
22 2
|
7天前
|
移动开发 前端开发 HTML5
HTML5实现酷炫个人产品推广、工具推广、信息推广、个人主页、个人介绍、酷炫官网、门户网站模板源码
HTML5实现酷炫个人产品推广、工具推广、信息推广、个人主页、个人介绍、酷炫官网、门户网站模板源码
|
14天前
|
移动开发 JavaScript 前端开发
【专栏:HTML进阶篇】HTML模板与Web组件:可复用的网页元素
【4月更文挑战第30天】HTML模板和Web组件提升网页开发效率和可维护性。HTML模板,如&lt;template&gt;元素和服务器端模板引擎,用于创建可复用的HTML结构。Web组件是自定义的HTML元素,结合影子DOM和模板,实现封装的可重用组件。两者助力构建高效、现代的网页和网站。
|
15天前
|
安全 Go 开发者
Golang深入浅出之-Go语言模板(text/template):动态生成HTML
【4月更文挑战第25天】Go语言的`text/template`和`html/template`库提供动态HTML生成。本文介绍了模板基础,如基本语法和数据绑定,以及常见问题和易错点,如忘记转义、未初始化变量、复杂逻辑处理和错误处理。建议使用`html/template`防止XSS攻击,初始化数据结构,分离业务逻辑,并严谨处理错误。示例展示了条件判断和循环结构。通过遵循最佳实践,开发者能更安全、高效地生成HTML。
22 0
|
25天前
|
机器人
机器人飞船404页面模板HTML源码
机器人飞船404页面模板HTML源码,源码由HTML+CSS+JS组成,记事本打开源码文件可以进行内容文字之类的修改,双击html文件可以本地运行效果,也可以上传到服务器里面,重定向这个界面
26 5
机器人飞船404页面模板HTML源码
|
2月前
100套HTML静态网页模板免费分享
100套HTML静态网页模板,设计的十分有特色,由于Github服务器原因可能下载速度较慢,已全部打包整理。
43 0
100套HTML静态网页模板免费分享
|
2月前
分享84个Html经典模板,总有一款适合您
分享84个Html经典模板,总有一款适合您
23 0