DevToolBox免费
博客

HTMX 指南 2026:无需 JavaScript 框架构建现代 Web 应用

13 分钟作者 DevToolBox

HTMX 是一个轻量级库,允许你直接从 HTML 访问现代浏览器功能,无需编写 JavaScript。通过使用 hx-get、hx-post 和 hx-swap 等属性扩展 HTML,HTMX 使用超媒体驱动的方式实现动态、交互式的 Web 应用。

什么是 HTMX?

HTMX 是一个无依赖的 JavaScript 库(压缩后约 14KB),通过自定义属性扩展 HTML,支持 AJAX 请求、服务器发送事件、WebSocket 连接和 CSS 过渡。

<!-- Add HTMX to your page -->
<script src="https://unpkg.com/htmx.org@2.0.0"></script>

<!-- A simple HTMX example: click to load content -->
<button hx-get="/api/greeting" hx-target="#result" hx-swap="innerHTML">
  Say Hello
</button>
<div id="result"></div>

<!-- The server returns HTML, not JSON -->
<!-- GET /api/greeting response: -->
<!-- <p>Hello, World! The time is 2026-02-23 10:30:00</p> -->

核心概念

HTMX 遵循 HATEOAS 原则。服务器发送 HTML,浏览器渲染它。这简化了架构,消除了单独 API 层和客户端状态管理的需求。

核心属性

HTMX 使用 HTML 属性来声明行为。核心属性控制发送什么 HTTP 请求以及如何更新页面。

<!-- HTTP method attributes -->
<button hx-get="/api/items">Load Items</button>
<form hx-post="/api/items">...</form>
<button hx-put="/api/items/1">Update</button>
<button hx-patch="/api/items/1">Partial Update</button>
<button hx-delete="/api/items/1">Delete</button>

<!-- Include values with requests -->
<input type="text" name="search" hx-get="/api/search"
       hx-trigger="keyup changed delay:300ms"
       hx-target="#search-results" />

<!-- Send additional values -->
<button hx-post="/api/vote"
        hx-vals='{"itemId": 42, "direction": "up"}'>
  Upvote
</button>

内容交换

hx-swap 属性控制响应 HTML 如何替换 DOM 中的内容。选项包括 innerHTML、outerHTML 等。

<!-- innerHTML: replace children (default) -->
<div hx-get="/items" hx-swap="innerHTML">Loading...</div>

<!-- outerHTML: replace the entire element -->
<div hx-get="/card" hx-swap="outerHTML">Old card</div>

<!-- beforeend: append to children -->
<ul hx-get="/more-items" hx-swap="beforeend">
  <li>Item 1</li>
</ul>

<!-- afterend: insert after the element -->
<tr hx-get="/next-row" hx-swap="afterend">...</tr>

<!-- Swap with transition timing -->
<div hx-get="/content" hx-swap="innerHTML swap:300ms settle:100ms">
  Content with transition
</div>

事件触发器

hx-trigger 属性控制何时发送请求。可以使用 delay、throttle、changed 和 once 等修饰符自定义触发器。

<!-- Trigger on keyup with 300ms debounce -->
<input hx-get="/search" hx-trigger="keyup changed delay:300ms" />

<!-- Trigger once when element becomes visible -->
<div hx-get="/lazy-content" hx-trigger="revealed">Loading...</div>

<!-- Trigger every 5 seconds (polling) -->
<div hx-get="/live-data" hx-trigger="every 5s">Current data</div>

<!-- Trigger on intersection observer -->
<div hx-get="/more" hx-trigger="intersect threshold:0.5">
  Load when 50% visible
</div>

<!-- Multiple triggers -->
<input hx-get="/validate"
       hx-trigger="change, keyup delay:500ms changed" />

常见模式

HTMX 支持许多传统上需要大量 JavaScript 代码的交互模式。

实时搜索

用单个属性实现搜索即输入功能。服务器返回匹配结果的 HTML,HTMX 将其交换到结果容器中。

<!-- Search as you type -->
<input type="search" name="q"
       hx-get="/api/search"
       hx-trigger="input changed delay:300ms, search"
       hx-target="#search-results"
       hx-indicator="#search-spinner"
       placeholder="Search users..." />

<span id="search-spinner" class="htmx-indicator">
  Searching...
</span>

<table>
  <thead><tr><th>Name</th><th>Email</th></tr></thead>
  <tbody id="search-results">
    <!-- Server returns <tr> elements -->
  </tbody>
</table>

无限滚动

当用户向下滚动时加载更多内容。revealed 触发器在元素进入视口时触发。

<!-- Infinite scroll -->
<div id="feed">
  <div class="post">Post 1</div>
  <div class="post">Post 2</div>
  <!-- Last element triggers loading more -->
  <div hx-get="/api/posts?page=2"
       hx-trigger="revealed"
       hx-swap="afterend"
       hx-select="div.post">
    Loading more...
  </div>
</div>

点击编辑

点击时将静态内容替换为编辑表单,保存后交换回更新的静态内容。

<!-- Click to edit pattern -->
<div hx-get="/contacts/1/edit" hx-trigger="click" hx-swap="outerHTML">
  <p>Name: Alice Johnson</p>
  <p>Email: alice@example.com</p>
  <small>Click to edit</small>
</div>

<!-- Server returns edit form: -->
<!--
<form hx-put="/contacts/1" hx-swap="outerHTML">
  <input name="name" value="Alice Johnson" />
  <input name="email" value="alice@example.com" />
  <button type="submit">Save</button>
  <button hx-get="/contacts/1" hx-swap="outerHTML">Cancel</button>
</form>
-->

服务端集成

HTMX 可与任何服务端语言或框架配合使用。服务器返回 HTML 片段而非 JSON。

Express.js (Node.js)

// Express.js server for HTMX
const express = require("express");
const app = express();

app.get("/api/search", (req, res) => {
  const query = req.query.q || "";
  const results = searchUsers(query);

  // Return HTML fragment, not JSON
  const html = results.map(user =>
    `<tr>
      <td>${user.name}</td>
      <td>${user.email}</td>
      <td>
        <button hx-delete="/api/users/${user.id}"
                hx-target="closest tr"
                hx-swap="outerHTML swap:500ms"
                hx-confirm="Delete ${user.name}?">
          Delete
        </button>
      </td>
    </tr>`
  ).join("");

  res.send(html);
});

Flask (Python)

# Flask server for HTMX
from flask import Flask, request, render_template_string

app = Flask(__name__)

@app.route("/api/search")
def search():
    query = request.args.get("q", "")
    results = search_users(query)

    return render_template_string("""
    {% for user in results %}
    <tr>
      <td>{{ user.name }}</td>
      <td>{{ user.email }}</td>
    </tr>
    {% endfor %}
    """, results=results)

高级特性

带外交换

使用 hx-swap-oob 从单个响应更新页面的多个部分。

<!-- Out-of-band swaps: update multiple elements -->
<!-- Main response (swaps into target): -->
<div id="main-content">
  <p>Item saved successfully!</p>
</div>

<!-- Additional out-of-band updates: -->
<span id="notification-count" hx-swap-oob="true">3</span>
<div id="sidebar-stats" hx-swap-oob="innerHTML">
  <p>Total items: 42</p>
</div>
<tr id="item-row-5" hx-swap-oob="outerHTML">
  <td>Updated Item</td>
  <td>2026-02-23</td>
</tr>

CSS 过渡

HTMX 在交换期间添加 CSS 类,可用于动画效果。

/* CSS transitions with HTMX */
.fade-in {
  opacity: 0;
  transition: opacity 300ms ease-in;
}
.fade-in.htmx-added {
  opacity: 0;
}
.fade-in.htmx-settling {
  opacity: 1;
}

/* Swapping out animation */
.htmx-swapping {
  opacity: 0;
  transition: opacity 200ms ease-out;
}

/* Loading indicator */
.htmx-indicator {
  display: none;
}
.htmx-request .htmx-indicator {
  display: inline-block;
}

HTMX vs JavaScript 框架

标准HTMXReact/Vue/Angular
Bundle size~14KB44KB+ (React + ReactDOM)
Learning curveLow (HTML attributes)High (JSX, hooks, state)
Build toolingNone requiredWebpack/Vite/etc required
TypeScriptNot neededStrongly recommended
State managementServer-sideClient-side (Redux, Zustand)
SEOExcellent (server HTML)Requires SSR/SSG
Offline supportLimitedService workers + PWA
Complex UIModerateExcellent
Server couplingTightLoose (API-driven)

最佳实践

  • 返回小的 HTML 片段,而非完整页面
  • 使用 hx-indicator 显示加载状态
  • 利用 hx-push-url 支持浏览器历史
  • 在链接和表单上使用 hx-boost 进行渐进增强
  • 尽可能保持服务器响应的幂等性
  • 使用 hx-swap-oob 从一个响应更新多个页面区域
  • 使用 hx-on::after-request 实现错误处理
  • 使用 preload 扩展预加载预期的导航

常见问题

HTMX 能取代 React 吗?

对于许多应用来说,可以。HTMX 擅长服务端渲染的中等交互性应用。对于高度交互的客户端应用,JavaScript 框架仍然更合适。

HTMX 对 SEO 友好吗?

非常友好。由于 HTMX 从服务器提供 HTML,搜索引擎可以直接抓取和索引内容,无需执行 JavaScript。

HTMX 能与 REST API 配合使用吗?

HTMX 设计用于返回 HTML 的超媒体 API。可以通过添加服务端渲染层来与现有 REST API 配合使用。

性能表现如何?

HTMX 非常轻量(14KB),页面加载快速,因为没有客户端渲染步骤。网络请求传输小的 HTML 片段而非 JSON。

HTMX 能处理复杂的状态管理吗?

HTMX 将状态管理移到服务器端。对于复杂的客户端状态,可能需要结合 Alpine.js 或原生 JS 使用。

𝕏 Twitterin LinkedIn
这篇文章有帮助吗?

保持更新

获取每周开发技巧和新工具通知。

无垃圾邮件,随时退订。

试试这些相关工具

JSXHTML to JSX{ }JSON Formatter

相关文章

Astro vs Next.js 2026:Islands 架构 vs React 服务器组件

Astro 与 Next.js 2026 深度对比:islands 架构、RSC、性能基准测试与 SEO。

Web 性能优化:2026 Core Web Vitals 指南

全面的 Web 性能优化和 Core Web Vitals 指南。学习如何通过图片、JavaScript、CSS 和缓存的实用技术改善 LCP、INP 和 CLS。