HTMX简介:无需借助JavaScript的动态HTML

译文
开发 前端
HTMX是HTML扩展语法,它把JavaScript换成了简单的标记(Markup),有望改变Web开发的方向。

译者 | 布加迪

审校 | 重楼

HTML让您可以使用扩展的HTML语法而不是JavaScript来实现交互性。HTMX直接在标记中为您提供了HTTP交互,它支持其他许多交互要求,无需借助JavaScript。这个有意思的想法最终可能会影响Web前端的工作方式。不妨看看如何使用HTMX以及什么让它如此引人注目。

HTMX简介

HTMX已经存在了一段时间,但它一直是比较低调的项目。它最近被GitHub Accelerator接受可能会改变这一切。其基本想法是拿来需要模板JavaScript和HTML交互的常见用例,径直使用HTML语法,无需借助JavaScript。许多交互使用HTMX变成了声明式交互。

这听起来大有希望,是不是?每个Web开发人员都知道有许多常见的样板案例。HTMX的开发者Carson Gross表示,他希望“完成HTML作为一种超文本,增强它的表现力,使它成为更高级的现代Web应用程序之外的一种颇有竞争力的选择。”

要快速体验一下,请看这个HTMX演示。大致来说,我们点击一个按钮来编辑用户对象上的字段。数据实际上被PUT(放入)到后端端点。您可以在图1中看到演示,请注意点击Show后底部框中的网络交互。

图1. 表单演示:HTMX图1. 表单演示:HTMX

通常,这一切都需要某种JavaScript,无论您使用什么框架。HTMX将交互转变为两个标记块:一个用于显示UI,另一个用于编辑UI,如代码片段1所示。

代码片段1:HTMX中的用户更新

<div hx-target="this" hx-swap="outerHTML">
    <div><label>First Name</label>: Joe</div>
    <div><label>Last Name</label>: Blow</div>
    <div><label>Email</label>: joe@blow.com</div>
    <button hx-get="/contact/1/edit" class="btn btn-primary">
    Click To Edit
    </button>
</div>
<!-- The edit: -->
<form hx-put="/contact/1" hx-target="this" hx-swap="outerHTML">
  <div>
    <label>First Name</label>
    <input type="text" name="firstName" value="Joe">
  </div>
  <div class="form-group">
    <label>Last Name</label>
    <input type="text" name="lastName" value="Blow">
  </div>
  <div class="form-group">
    <label>Email Address</label>
    <input type="email" name="email" value="joe@blow.com">
  </div>
  <button class="btn">Submit</button>
  <button class="btn" hx-get="/contact/1">Cancel</button>
</form>

如果您查看代码片段1中的标记,就很容易看出具体发生了什么:hx-swap属性在编辑之前为div提供了HTML,而outerHTML告诉框架它如何与其中的动态内容相关联。可编辑版本作为含有x-put属性的表单元素出现,该属性标识PUT HTML方法以及要使用的端点。

问题变成了如何在不借助任何JavaScript的情况下实现这种“交换”和随后的PUT?答案很简单:它为编辑标记使用HTML的服务器端呈现,并将表单编组抽象到框架中。JavaScript仍然在幕后工作。实际上,我们得到了一种粒度更细的HTML语法,它可以只加载页面部分而不是整个页面,并可以提交Ajax请求。

这是实际DRY原理的一个有趣的例子。即使是像React这样的技术,也有一定数量的样板代码将信息从一种形式转换为另一种形式。当然,HTMX没有完全消除这种情况,但它已经将工作转移到服务器上。

服务器端HTMX

现在不妨考虑服务器端。许多服务器端技术都使用了HTMX,因为正如Gross所说,HTMX“与后端无关”。它不在乎您使用什么后端,只要它生成HTML就行。”为了大致了解它是如何工作的,不妨看一个使用Express的TODO示例以及Pug HTML模板引擎。这个示例是经典TODO应用程序的实现。

首先,使用以下命令从Express输出现有的待办事项:

res.render('index', { todos: filteredTodos, filter, itemsLeft: getItemsLeft() 
});

该命令使用内存中的待办事项集合,并使用典型格式的Pug模板来呈现它们,只不过它含有驱动HTMX交互的特殊hx-属性。比如说,代码片段2显示了POST新待办事项的表单。

代码片段2. 拥有HTMX属性的表单POST

form(hx-post="/todos", hx-target="#todo-list", hx-swap="afterbegin", _="on htmx:afterOnLoad set #txtTodo.value to ''")
  input#txtTodo.new-todo(name="todo",placeholder='What needs to be done?', autofocus='')

您可以在这里(https://htmx.org/docs/#swapping)看到afterbegin属性如何将新内容放在列表中它所属的位置的。on htmx脚本是Hyperscript的一个例子,Hyperscript是一种简化的脚本语言。它经常与HTMX结合使用,但严格来说并不是HTMX的一部分,也不是需要它才能使用HTMX。实际上,这里使用on htmx来处理在创建新待办事项之后设置输入表单的值。

另一个示例是,代码片段3显示了用于待办事项编辑的Pug模板。

代码片段3. 在PUG中编辑服务器端模板

form(hx-post="/todos/update/" + todo.id)
      input.edit(type="text", name="name",value=todo.name)

在代码片段3中,标记使用hx-post属性指示将编辑后的待办事项的JSON发送到何处。从这些示例中得出的结论是我在前面提到的:服务器负责提供HTML(用HTML标记装饰),采用适当大小的块,以填充前端用于各种交互所需的屏幕的不同部分。HTMX客户端将根据属性将它们放置在本该所属的位置,还将处理这项任务:发送适当的数据供服务使用。

负责接收数据的端点可以像典型端点一样操作,不同之处在于响应应该是必需的HTMX。比如,在代码片段4中,您可以看到Express服务器如何处理POST以创建新的待办事项。

代码片段4. 处理待办事项创建

app.post('/todos', (req, res) => {
  const { todo } = req.body;
  const newTodo = { 
        id: uuid(),
    name: todo, 
        done: false 
  };
    todos.push(newTodo);
  let template = pug.compileFile('views/includes/todo-item.pug');
  let markup = template({ todo: newTodo});
  template = pug.compileFile('views/includes/item-count.pug');
    markup  += template({ itemsLeft: getItemsLeft()});
    res.send(markup);
});

代码片段4是一个典型的POST主体处理程序,它从表单数据中获取值,并用它创建一个新的业务对象(newTodo)。然而,它随后使用这些值来填充Pug模板,并将其发回给客户端,以便用作插入到前端上的Todo列表。

服务器端技术的其他例子包括在Java界结合使用HTMX和Spring Boot与Thymeleaf,在Python界结合使用Spring Boot和Django。

使用HTMX的客户端模板

这种模式的另一种变体得到HTMX的支持,它使用客户端模板。这一层在客户机中运行,接收来自服务器的JSON,并在服务器上进行标记翻译。当我向Gross询问如何使用带有JSON的可充分利用REST的服务时,他指出可以使用客户端模板来实现,但要注意的是REST通常被误解了。

那么一个相反的问题是,我们如何向服务器提交JSON而不是默认的表单编码?再说一次,这有一个相应的扩展,即JSON-ENC

结论

考虑HTMX会引发一大堆想法同时出现。结果是,这个概念与项目本身一样有益。作为一个成熟的项目,HTMX可能不会像现在这样精确地工作,但它已经证明了具有重大影响力。最引人注目的是这个想法:处理所有这些非常常见的Ajax风格的请求,这通常意味着使用fetch()或类似的东西,仅仅只有HTML属性。这样更简单、更干净,而且所有东西都放在一个地方。标记具体做什么一目了然。

我对服务器端标记生成比较矛盾。开发人员习惯于为此目的处理JSON,引入标记只是为客户端创建添加了一个步骤。我们已经看到了许多服务器端方法,它们似乎总是混淆HTML、JavaScript和CSS这个强大的组合,而这个组合最终将继续笑到最后。也许这一回会有所不同,这里存在明显的钟摆效应。

当然,还有客户端模板选项,它使服务器成为一个熟悉的JSON发射器(emitter)。我试着想象它在一个大型软件项目中会如何工作。它会降低大规模项目的总体复杂性吗?

Gross对复杂性有其自己的看法,他的想法在HTMX的设计中得到了体现。这项技术希望通过将超文本重新作为Web应用程序的状态机制来达到简化的目的。这个示例(表明了这个想法具体是如何实现的。使用JSON作为协议,意味着使客户端更智能、更复杂,并且使架构少一点自我描述。

也许它完全行得通。如果我们通过扩展底层语言HTML以实际处理现代需求(就像Ajax那样)、避免固有的复杂性,有望回到更简单的时代。标记将再次成为中心数据描述符,足以描述UI以及线上的数据。

原文标题:Intro to HTMX: Dynamic HTML without JavaScript,作者:Matthew Tyson

责任编辑:华轩 来源: 51CTO
相关推荐

2023-10-19 08:38:18

2022-06-23 09:00:00

JavaScriptHTML应用程序

2023-09-03 19:43:46

htmxJavaScript网络

2017-01-16 09:26:07

2010-09-25 08:44:34

捆绑后门

2010-09-17 16:23:53

分离捆绑后门

2024-01-15 00:35:23

JavaScript框架HTML

2012-05-30 09:22:56

Hybrid App助HTML5JavaScript

2023-09-28 13:30:06

HtmxWebJavascript

2022-02-11 14:41:22

树莓派操作系统系统安装

2024-05-08 08:20:20

HTMX前端开发

2022-07-18 08:48:06

HtmxHTML

2020-12-25 10:28:41

JavaScript模块module

2013-08-26 17:41:43

JavaScriptWindows 8.1

2022-12-02 08:00:00

JavaScriptAstro前端

2022-10-20 15:43:39

htmxDjango技术栈

2024-03-22 11:40:40

Node.jsNodeCRUD

2020-07-20 07:56:28

JavaScript开发技术

2020-12-02 08:28:58

JavaScript API 服务器

2020-08-31 07:14:03

DNSKubernetns 负载均衡
点赞
收藏

51CTO技术栈公众号