htmx Chinese docs

htmx Chinese docs

最后更新于

点击以载入内容:
文档 附录 示例 交流
 <!-- 从 unpkg 中引入脚本 -->
  <script src="https://unpkg.com/[email protected]"></script>
  <!-- have a button POST a click via AJAX -->
  <button hx-post="/blog" hx-swap="outerHTML">
    点我
  </button>

htmx 是 intercooler.js 的下一代
兼容性:支持所有主流浏览器和 IE11 以上版本

要理解 htmx 的工作原理,先来看一个锚标记

<a href="/blog">Blog</a>

这个锚标记告诉浏览器

当用户点击链接时,发起一个指向 /blog 的 http get 请求并把内容渲染到浏览器窗口内

既然这样,来看一下这个代码:

	<div hx-post="/blog"
       	hx-trigger="click"
       	hx-target="#parent-div"
       	hx-swap="outerHTML">
    	点我!
  	</div>
<div id="parent-div"></div>

这告诉 htmx:

当用户点击这个 div 时,发出一个指向 /blog 的 http post 请求并使用请求到的内容替换 id 为 parent-div 的元素的内容

htmx 可以实现这些功能:

  • 在任何元素上发起 http 请求
  • 任何事件都可以触发请求
  • 可以使用任何 HTTP 动词
  • 可以替换任何元素的内容(整个 html 也可以)

如果你愿意的话,你可以加上 data- 前缀

<a data-hx-post="/blog">点我!</a>

npm 使用 htmx.org 安装

<script src="https://unpkg.com/[email protected]"></script>

htmx 的核心功能是从 HTML 中直接发起 ajax 请求

属性作用
hx-get发起一个 GET 请求到对应 URL
hx-post发起一个 POST 请求到对应 URL
hx-put发起一个 PUT 请求到对应 URL
hx-patch发起一个 PATCH 请求到对应 URL
hx-delete发起一个 DELETE 请求到对应 URL

例如

  <div hx-put="/blog">
    Put To Messages
  </div>

这告诉浏览器

当用户点击 div 时,发起一个 put 请求并加载响应内容到 div 中

默认状态下,

  • inputtextarea & select 触发 change 事件
  • form 触发 submit 事件
  • 其他所有事件由 click 触发

hx-trigger 用于定义触发方式

这是一个鼠标移入事件

   <div hx-post="/blog" hx-trigger="mouseenter">
      [过来鼠标🖱️!]
   </div>

如果你想让该请求只触发一次,使用 once 修饰符

   <div hx-post="/blog" hx-trigger="mouseenter once">
     [Here Mouse, Mouse!]
   </div>

其它修饰符

  • changed – 仅在该元素的值变化时触发
  • cooldown:<时间> – 触发延迟,如 1s

这是一个主动搜索的例子

   <input type="text" name="q" 
          hx-get="/" 
          hx-trigger="keyup changed delay:500ms" 
          hx-target="#search-results" 
          placeholder="搜索..."/>
    <div id="search-results"></div>

这个会在你输入关键词的 500ms 后执行搜索

你可以在 hx-trigger 中使用多个值,用空格分隔

  • load – 元素加载完成后立即执行
  • revealed – 在元素第一次出现在可视范围内
  <div hx-get="/blog" hx-trigger="every 2s">
  </div>

这告诉 htmx

每隔 2 秒执行一次指向 /blog 的 GET 请求并写入内容到 div 中

要停止循环,需要目标地址返回状态码 286

<div hx-get="/blog" 
     hx-trigger="load delay:1s"
     hx-swap="outerHTML">
     
</div>

如果 /blog 总是返回与上方一样的 div ,那么这将永远每隔 1s 执行下去
这将在你制作进度条时十分有用

  <button hx-get="/blog">
      点我!
     <img class="htmx-indicator" src="/spinner.gif"/>
  </button>

当 ajax 请求发出但是服务器还没有响应时显示一个加载动画可以避免用户认为该链接无效
带有 htmx-indicator 类的元素的默认透明度将会是 0(推荐加入 pointer-events: none; 样式)
当 ajax 请求发出时,发出请求的元素内部带有 htmx-indicator 类的元素的透明度都会被改为 1

在上面的代码里,当我们点击按钮时,按钮元素会被加入类 htmx-request 并将带有类 htmx-indicator 的子元素的透明度改为 1
目前 SVG动画 比较流行

如果你想要自定义动画的出现方式,可以使用像下面这样的 css

    .htmx-indicator{
        display:none;
    }
    .htmx-request .my-indicator{
        display:inline;
    }
    .htmx-request.my-indicator{
        display:inline;
    }

如果你想把 htmx-request 类加到其它元素上,可以使用 hx-indicator 属性

  <div>
      <button hx-get="/blog" hx-indicator="#indicator">
        Click Me!
      </button>
      <img id="indicator" class="htmx-indicator" src="/spinner.gif"/>  
  </div>

如果你想把返回的内容加载到特定的元素里,可使用 hx-target 属性。比如下面这个即时搜索代码(具体效果可以去看百度搜索电脑版网页或 WordPress 后台主题/插件搜索功能)

   <input type="text" name="q" 
          hx-get="/" 
          hx-trigger="keyup delay:500ms changed" 
          hx-target="#search-results"
          placeholder="搜索..."/>
    <div id="search-results"></div>

你会看到搜索结果加载在 div#search-results 中,而不是搜索框中

使用 hx-swap 属性定义替换方法

方法说明
innerHTML默认值, 把内容放到目标元素内
outerHTML用返回的数据替换整个目标元素
afterbegin在目标元素的第一个子元素前插入
beforebegin在目标元素前插入
beforeend追加在目标元素的最后一个子元素后
afterend追加在目标元素后

如果你想直接将内容插入到 DOM 中,请在目标网页中使用 id 和 hx-swap-oob 属性

<!--请将此代码写在目标地址中-->
<div id="message" hx-swap-oob="true">将我直接插入!</div>
其它内容

在这个代码中,div#message 将会直接插入 DOM 中,而“其它内容”的插入方式与上方介绍相同
你可以使用此方法以使用其它请求推送更新
⚠️out of band 元素必须是最高级元素,不可是任何子元素

指定内容以插入

如果你只想插入目标地址中的特定元素,请使用 hx-select 属性,并使用 css 选择器的格式选择元素

默认情况下,当元素发起请求时会包括它的值,如果它是一个表单,将会包括它 的所有输入值

另外,如果该元素发起了非 GET 请求,最近的一个封闭表单的值也会被包含

如果你想包含其它元素的值,请使用 hx-include 属性并使用 css 选择器格式

如果你想要排除某个元素的值,请使用 hx-params 属性

高级参数设置请使用 configRequest.htmx 事件

htmx 提供 hx-boost 属性,该属性可以增强锚点和表单。具有此属性的锚点和表单将会转化为 ajax 请求,并默认指向 body

一个例子:

<div hx-boost="true">
    <a href="/blog">Blog</a>
</div>

此 div 中的锚标记将会执行一个 ajax GET 请求并将 /blog 的内容插入 body 中
此功能类似于 Turbolinks 并可使用渐进增强(progressive enhancement)

实验性功能

htmx 允许你使用 WebSocketsServer Sent Events

如果你想在 htmx 中使用 WebSockets 连接,请使用 hx-ws 属性

  <div hx-ws="connect wss:/chatroom">
    <div id="chat_room">
      ...
    </div>
    <form hx-ws="send:submit">
        <input name="chat_message">
    </form>
  </div>

source 声明建立了连接,send 声明将表单在 submit 上提交到 socket

更多信息请见 hx-ws 属性页

Server Sent Events 允许从服务器发送事件到用户端。它为服务器与客户端之间的交流提供了一个更高级的机制。

如果你想要一个元素响应 Server Sent Events,你需要做以下两件事:

  1. 定义 SSE 源:在父元素上添加 hx-sse 属性并将属性值设为 connect <url>
  2. 定义被触发的子元素:在该子元素上添加 hx-trigger="sse:<事件名>"

这是一个例子:

    <body hx-sse="connect /news_updates">
        <div hx-trigger="sse:new_news" hx-get="/news"></div>
    </body>

根据你的设置,此方法可能比上面的循环示例更高效,因为此方法会大大减少请求量

htmx 提供一个简单的机制来支持历史记录API

如果你想让一个元素请求的地址显示在浏览器地址栏并添加历史记录,请使用 hx-push-url 属性

<a hx-get="/blog" hx-push-url="true">Blog</a>

当用户点击此链接时,htmx 会在发起 /blog 请求前将当前的 DOM 内容存入快照,然后显示内容并在历史记录中添加新项。

当用户点击后退按钮时,htmx 会将存储的历史记录数据显示回页面中,并模拟回到了上一步。

默认情况下,htmx 将会把整个 body 存入历史记录。通常这没有什么问题,但是你可能只想让一部分元素可以回滚,那么请使用 hx-history-elt 属性指定。

小心:所有页面都必须有该元素才能使之正常工作!

htmx 会尝试响应 AJAX 请求并将其转化为 HTML,通常为 HTML 片段(一个完整的 HTML 使用 hx-select 将会很有用),然后,htmx 将内容用指定的替换方法插入到页面的指定对象中。

但有时你可能不想替换任何东西,但客户端仍需发起请求(见下方),这种情况下你只需返回状态码 204 - 无内容 即可

若 htmx 收到了错误响应(如 404、501 等),将会触发 responseError.htmx 事件,你可以对其进行处理。

当发生连接错误时,sendError.htmx 事件将被触发。

Header介绍
X-HX-Request将被设为 “true”
X-HX-Trigger将被设为触发请求的元素的 ID
X-HX-Trigger-Name将被设为触发请求的元素的名称
X-HX-Target将被设为目标元素的 ID
X-HX-Current-URL将被设为浏览器当前地址栏的 URL
X-HX-Prompt将被设为用户通过 hx-prompt 输入的数据
X-HX-Event-Target该事件触发请求的原始目标的 ID
X-HX-Active-Element当前活动元素的 ID
X-HX-Active-Element-Name当前活动元素的名称
X-HX-Active-Element-Value当前活动元素的值
X-HTTP-Method-Override非 GET 和 POST 请求的 HTTP 动词
  • X-HX-Trigger – 用于触发客户端事件, 例子见 文档.
  • X-HX-Push – 用于改变浏览器地址栏地址
  • 元素被触发,开始发出请求
    • 收集请求所需的数据
    • htmx-request 类被应用到相应的元素上
    • 然后用 AJAX 发起异步请求
      • 收到相应后,目标元素会被应用 htmx-swapping 类
      • 替换延迟(swap delay)开始生效 (见 hx-swap-delay 属性)
      • 内容替换完成
        • 从目标元素中移除 htmx-swapping 类
        • 应用类 htmx-settling 至目标元素
        • 结束延迟(settle delay)完成 (默认: 100ms)
        • DOM 加载完成
        • 从目标元素中移除 htmx-settling 类

你可以使用 htmx-swapping 和 htmx-settling 类来创建 CSS 页面过渡动画.

htmx 允许你仅使用 CSS 和 HTML 创建过渡动画。
更多信息见 动画帮助

htmx 可以使用扩展(插件)来自定义某些行为。
扩展需用 JavaScript 定义并使用属性 hx-ext 来调用

<button hx-post="/blog" hx-ext="debug">这个按钮使用了“调试”扩展</button>

如果你想添加你自己的扩展,请阅读 扩展文档

扩展名称简介
json-enc在请求 body 中使用 JSON 编码, 而不是默认的 x-www-form-urlencoded
morphdom-swap使用 morphdom 库作为 htmx 的内容替换机制
client-side-templates允许客户端处理 JSON 响应
path-depsan extension for expressing path-based dependencies 类似于 intercoolerjs
class-tools定时增加或移除元素上的类

完整列表见 扩展文档

htmx 有一个强大的事件机制,同时可作为日志记录系统。

如果你想使用一个已有的 htmx 事件,可使用下方的 JavaScript 代码

  htmx.on("load.htmx", function(evt) {
        myJavascriptLib.init(evt.details.elt);  
  });

此事件将在 htmx 每次加载元素至 DOM 后执行。并且同样适用于加载事件。但事实上这太普通了,你还可以使用此简化函数:

  htmx.onLoad(function(target) {
        myJavascriptLib.init(target);  
  });

效果与第一个例子相同,但是这个更易于理解
其它事件请阅读 附录

如果你在 htmx.logger 上设置一个记录,所有事件都会被记录,这将在你查找问题时非常有用。

    htmx.logger = function(elt, event, data) {
        if(console) {
            console.log(event, elt, data);
        }
    }

htmx 可以把错误信息发送到 hx-error-url 属性定义的 URL 中,这将有助于调试客户端问题

htmx 还有一个更简单的方法:

htmx.logAll();

如果您想在开发时记录所有内容,你可以使用上方的 JavaScript

待翻译

你可以改变 htmx 的一些默认设置

配置信息
htmx.config.historyEnabled默认为 true, 仅仅在测试时有用
htmx.config.historyCacheSize默认为 10
htmx.config.defaultSwapStyle默认为 innerHTML
htmx.config.defaultSwapDelay默认为 0
htmx.config.defaultSettleDelay默认为 100
htmx.config.includeIndicatorStyles默认为 true (是否加载 htmx-indicator 的默认样式, 必须在引用 htmx.min.js 之前在 meta 中设置)

你可以直接用 JavaScript 设置它们,当然你也可以使用 meta 标签,比如:

<meta name="htmx-config" content='{"defaultSwapStyle":"outerHTML"}'>

就是这些,是不是很简单?你并不需要太多代码就可以完成它。

 

5 3 个评分
Vote
Subscription
Remind me of the
guest
1 Comment(s)
Most votes
Newest Oldest
Inline comment
Show all comments