内容
¥Contents
¥htmx in a Nutshell
htmx 是一个允许你直接从 HTML 访问现代浏览器功能的库,而不是使用 javascript。
¥htmx is a library that allows you to access modern browser features directly from HTML, rather than using javascript.
要了解 htmx,首先让我们看一下锚标记:
¥To understand htmx, first let’s take a look at an anchor tag:
<a href="/blog">Blog</a>
此锚标记告诉浏览器:
¥This anchor tag tells a browser:
“当用户点击此链接时,向 ‘/blog’ 发出 HTTP GET 请求,并将响应内容加载到浏览器窗口中”。
¥“When a user clicks on this link, issue an HTTP GET request to ‘/blog’ and load the response content into the browser window”.
考虑到这一点,请考虑以下 HTML 部分:
¥With that in mind, consider the following bit of HTML:
<button hx-post="/clicked"
hx-trigger="click"
hx-target="#parent-div"
hx-swap="outerHTML">
Click Me!
</button>
这告诉 htmx:
¥This tells htmx:
“当用户单击此按钮时,向“/clicked”发出 HTTP POST 请求,并使用响应中的内容替换 DOM 中 ID 为
parent-div
的元素”¥“When a user clicks on this button, issue an HTTP POST request to ‘/clicked’ and use the content from the response to replace the element with the id
parent-div
in the DOM”
htmx 扩展并概括了 HTML 作为超文本的核心思想,在语言中直接开辟了更多可能性:
¥htmx extends and generalizes the core idea of HTML as a hypertext, opening up many more possibilities directly within the language:
现在任何元素(而不仅仅是锚点和表单)都可以发出 HTTP 请求
¥Now any element, not just anchors and forms, can issue an HTTP request
现在任何事件(而不仅仅是点击或表单提交)都可以触发请求
¥Now any event, not just clicks or form submissions, can trigger requests
现在可以使用任何 HTTP 动词,而不仅仅是 GET
和 POST
¥Now any HTTP verb, not just GET
and POST
, can be used
现在任何元素(而不仅仅是整个窗口)都可以成为请求更新的目标
¥Now any element, not just the entire window, can be the target for update by the request
请注意,当你使用 htmx 时,在服务器端你通常使用 HTML 而不是 JSON 进行响应。这让你牢牢地呆在 原始 Web 编程模型 内,使用 超文本作为应用状态的引擎 甚至不需要真正理解这个概念。
¥Note that when you are using htmx, on the server side you typically respond with HTML, not JSON. This keeps you firmly within the original web programming model, using Hypertext As The Engine Of Application State without even needing to really understand that concept.
值得一提的是,如果你愿意,你可以在使用 htmx 时使用 data-
前缀:
¥It’s worth mentioning that, if you prefer, you can use the data-
prefix when using htmx:
<a data-hx-post="/click">Click Me!</a>
如果你了解有关 htmx 的概念并希望了解库的怪癖,请参阅我们的 QUIRKS 页面。
¥If you understand the concepts around htmx and want to see the quirks of the library, please see our QUIRKS page.
¥1.x to 2.x Migration Guide
htmx 的 版本 1 仍然受支持并支持 IE11,但 htmx 的最新版本是 2.x。
¥Version 1 of htmx is still supported and supports IE11, but the latest version of htmx is 2.x.
如果你要从 htmx 1.x 迁移到 htmx 2.x,请参阅 htmx 1.x 迁移指南。
¥If you are migrating to htmx 2.x from htmx 1.x, please see the htmx 1.x migration guide.
如果你要从 intercooler.js 迁移到 htmx,请参阅 intercooler 迁移指南。
¥If you are migrating to htmx from intercooler.js, please see the intercooler migration guide.
¥Installing
Htmx 是一个无依赖、面向浏览器的 javascript 库。这意味着使用它就像在文档头中添加 <script>
标签一样简单。不需要构建系统来使用它。
¥Htmx is a dependency-free, browser-oriented javascript library. This means that using it is as simple as adding a <script>
tag to your document head. There is no need for a build system to use it.
¥Via A CDN (e.g. unpkg.com)
开始使用 htmx 的最快方法是通过 CDN 加载它。你可以简单地将其添加到 head 标签并开始:
¥The fastest way to get going with htmx is to load it via a CDN. You can simply add this to your head tag and get going:
<script src="https://unpkg.com/htmx.org@2.0.4" integrity="sha384-HGfztofotfshcF7+8n44JQL2oJmowVChPTg48S+jvZoztPfvwD79OC/LTtG6dMp+" crossorigin="anonymous"></script>
还有一个未缩小的版本:
¥An unminified version is also available as well:
<script src="https://unpkg.com/htmx.org@2.0.4/dist/htmx.js" integrity="sha384-oeUn82QNXPuVkGCkcrInrS1twIxKhkZiFfr2TdiuObZ3n3yIeMiqcRzkIcguaof1" crossorigin="anonymous"></script>
虽然 CDN 方法非常简单,但你可能需要考虑 在生产中不使用 CDN。
¥While the CDN approach is extremely simple, you may want to consider not using CDNs in production.
¥Download a copy
安装 htmx 的下一个最简单的方法是将其复制到你的项目中。
¥The next easiest way to install htmx is to simply copy it into your project.
下载 htmx.min.js
来自 unpkg.com 并将其添加到项目中的相应目录中,并在必要时使用 <script>
标签将其包含在内:
¥Download htmx.min.js
from unpkg.com and add it to the appropriate directory in your project
and include it where necessary with a <script>
tag:
<script src="/path/to/htmx.min.js"></script>
对于 npm 样式的构建系统,你可以通过 npm 安装 htmx:
¥For npm-style build systems, you can install htmx via npm:
npm install htmx.org@2.0.4
安装后,你需要使用适当的工具来使用 node_modules/htmx.org/dist/htmx.js
(或 .min.js
)。例如,你可以将 htmx 与一些扩展和项目特定代码打包在一起。
¥After installing, you’ll need to use appropriate tooling to use node_modules/htmx.org/dist/htmx.js
(or .min.js
).
For example, you might bundle htmx with some extensions and project-specific code.
如果你使用 webpack 来管理你的 javascript:
¥If you are using webpack to manage your javascript:
通过你最喜欢的包管理器(如 npm 或 yarn)安装 htmx
¥Install htmx
via your favourite package manager (like npm or yarn)
将导入添加到你的 index.js
¥Add the import to your index.js
import 'htmx.org';
如果你想要使用全局 htmx
变量(推荐),则需要将其注入窗口范围:
¥If you want to use the global htmx
variable (recommended), you need to inject it to the window scope:
创建自定义 JS 文件
¥Create a custom JS file
将此文件导入到你的 index.js
(在步骤 2 的导入下方)
¥Import this file to your index.js
(below the import from step 2)
import 'path/to/my_custom.js';
然后将此代码添加到文件中:
¥Then add this code to the file:
window.htmx = require('htmx.org');
最后,重建你的包
¥Finally, rebuild your bundle
htmx 的核心是一组属性,允许你直接从 HTML 发出 AJAX 请求:
¥The core of htmx is a set of attributes that allow you to issue AJAX requests directly from HTML:
属性 | 描述 |
---|---|
hx-get | 向给定的 URL 发出 GET 请求 |
hx-post | 向给定的 URL 发出 POST 请求 |
hx-put | 向给定的 URL 发出 PUT 请求 |
hx-patch | 向给定的 URL 发出 PATCH 请求 |
hx-delete | 向给定的 URL 发出 DELETE 请求 |
每个属性都需要一个 URL 来发出 AJAX 请求。当元素为 triggered 时,元素将向给定的 URL 发出指定类型的请求:
¥Each of these attributes takes a URL to issue an AJAX request to. The element will issue a request of the specified type to the given URL when the element is triggered:
<button hx-put="/messages">
Put To Messages
</button>
这告诉浏览器:
¥This tells the browser:
当用户单击此按钮时,向 URL /messages 发出 PUT 请求并将响应加载到按钮中
¥When a user clicks on this button, issue a PUT request to the URL /messages and load the response into the button
¥Triggering Requests
默认情况下,AJAX 请求由元素的 “natural” 事件触发:
¥By default, AJAX requests are triggered by the “natural” event of an element:
input
、textarea
和 select
在 change
事件上触发
¥input
, textarea
& select
are triggered on the change
event
form
在 submit
事件上触发
¥form
is triggered on the submit
event
其他一切都由 click
事件触发
¥everything else is triggered by the click
event
如果你想要不同的行为,你可以使用 hx-trigger 属性来指定哪个事件将导致请求。
¥If you want different behavior you can use the hx-trigger attribute to specify which event will cause the request.
以下是当鼠标进入时发布到 /mouse_entered
的 div
:
¥Here is a div
that posts to /mouse_entered
when a mouse enters it:
<div hx-post="/mouse_entered" hx-trigger="mouseenter">
[Here Mouse, Mouse!]
</div>
¥Trigger Modifiers
触发器还可以具有一些其他修饰符来更改其行为。例如,如果你希望请求仅发生一次,则可以使用 once
修饰符作为触发器:
¥A trigger can also have a few additional modifiers that change its behavior. For example, if you want a request to only
happen once, you can use the once
modifier for the trigger:
<div hx-post="/mouse_entered" hx-trigger="mouseenter once">
[Here Mouse, Mouse!]
</div>
你可以用于触发器的其他修饰符是:
¥Other modifiers you can use for triggers are:
changed
- 仅在元素的值发生变化时发出请求
¥changed
- only issue a request if the value of the element has changed
delay:<time interval>
- 在发出请求之前等待给定的时间(例如 1s
)。如果事件再次触发,倒计时将被重置。
¥delay:<time interval>
- wait the given amount of time (e.g. 1s
) before
issuing the request. If the event triggers again, the countdown is reset.
throttle:<time interval>
- 在发出请求之前等待给定的时间(例如 1s
)。与 delay
不同,如果在达到时间限制之前发生新事件,则该事件将被丢弃,因此请求将在时间段结束时触发。
¥throttle:<time interval>
- wait the given amount of time (e.g. 1s
) before
issuing the request. Unlike delay
if a new event occurs before the time limit is hit the event will be discarded,
so the request will trigger at the end of the time period.
from:<CSS Selector>
- 监听不同元素上的事件。这可以用于键盘快捷键之类的东西。请注意,如果页面发生变化,则不会重新评估此 CSS 选择器。
¥from:<CSS Selector>
- listen for the event on a different element. This can be used for things like keyboard shortcuts. Note that this CSS selector is not re-evaluated if the page changes.
你可以使用这些属性来实现许多常见的 UX 模式,例如 主动搜索:
¥You can use these attributes to implement many common UX patterns, such as Active Search:
<input type="text" name="q"
hx-get="/trigger_delay"
hx-trigger="keyup changed delay:500ms"
hx-target="#search-results"
placeholder="Search...">
<div id="search-results"></div>
如果输入已更改,则此输入将在按键事件发生后 500 毫秒发出请求,并将结果插入到 ID 为 search-results
的 div
中。
¥This input will issue a request 500 milliseconds after a key up event if the input has been changed and inserts the results
into the div
with the id search-results
.
可以在 hx-trigger 属性中指定多个触发器,用逗号分隔。
¥Multiple triggers can be specified in the hx-trigger attribute, separated by commas.
¥Trigger Filters
你还可以通过在事件名称后使用方括号来应用触发过滤器,将要评估的 javascript 表达式括起来。如果表达式的计算结果为 true
,则事件将触发,否则不会触发。
¥You may also apply trigger filters by using square brackets after the event name, enclosing a javascript expression that
will be evaluated. If the expression evaluates to true
the event will trigger, otherwise it will not.
以下是仅在元素的 Control-Click 上触发的示例
¥Here is an example that triggers only on a Control-Click of the element
<div hx-get="/clicked" hx-trigger="click[ctrlKey]">
Control Click Me
</div>
像 ctrlKey
这样的属性将首先针对触发事件进行解析,然后针对全局范围进行解析。this
符号将设置为当前元素。
¥Properties like ctrlKey
will be resolved against the triggering event first, then against the global scope. The
this
symbol will be set to the current element.
¥Special Events
htmx 提供了一些用于 hx-trigger 的特殊事件:
¥htmx provides a few special events for use in hx-trigger:
load
- 当元素首次加载时触发一次
¥load
- fires once when the element is first loaded
revealed
- 当元素首次滚动到视口时触发一次
¥revealed
- fires once when an element first scrolls into the viewport
intersect
- 当元素首次与视口相交时触发一次。这支持两个附加选项:
¥intersect
- fires once when an element first intersects the viewport. This supports two additional options:
root:<selector>
- 用于交集的根元素的 CSS 选择器
¥root:<selector>
- a CSS selector of the root element for intersection
threshold:<float>
- 0.0 和 1.0 之间的浮点数,表示触发事件的交集量
¥threshold:<float>
- a floating point number between 0.0 and 1.0, indicating what amount of intersection to fire the event on
如果你有高级用例,你还可以使用自定义事件来触发请求。
¥You can also use custom events to trigger requests if you have an advanced use case.
¥Polling
如果你希望元素轮询给定的 URL 而不是等待事件,你可以将 every
语法与 hx-trigger
属性一起使用:
¥If you want an element to poll the given URL rather than wait for an event, you can use the every
syntax
with the hx-trigger
attribute:
<div hx-get="/news" hx-trigger="every 2s"></div>
这告诉 htmx
¥This tells htmx
每 2 秒向 /news 发出一次 GET,并将响应加载到 div 中
¥Every 2 seconds, issue a GET to /news and load the response into the div
如果你想要停止从服务器响应进行轮询,可以使用 HTTP 响应代码 286
进行响应,元素将取消轮询。
¥If you want to stop polling from a server response you can respond with the HTTP response code 286
and the element will cancel the polling.
¥Load Polling
可用于在 htmx 中实现轮询的另一种技术是 “加载轮询”,其中元素指定 load
触发器以及延迟,并用响应替换自身:
¥Another technique that can be used to achieve polling in htmx is “load polling”, where an element specifies
a load
trigger along with a delay, and replaces itself with the response:
<div hx-get="/messages"
hx-trigger="load delay:1s"
hx-swap="outerHTML">
</div>
如果 /messages
端点继续返回以这种方式设置的 div,它将每秒让 “轮询” 返回到 URL。
¥If the /messages
end point keeps returning a div set up this way, it will keep “polling” back to the URL every
second.
在轮询具有结束点的情况下,负载轮询很有用,例如当你向用户显示 进度条 时。
¥Load polling can be useful in situations where a poll has an end point at which point the polling terminates, such as when you are showing the user a progress bar.
¥Request Indicators
发出 AJAX 请求时,通常最好让用户知道正在发生某些事情,因为浏览器不会向他们提供任何反馈。你可以使用 htmx-indicator
类在 htmx 中完成此操作。
¥When an AJAX request is issued it is often good to let the user know that something is happening since the browser
will not give them any feedback. You can accomplish this in htmx by using htmx-indicator
class.
htmx-indicator
类的定义使得具有此类的任何元素的不透明度默认为 0,使其不可见但存在于 DOM 中。
¥The htmx-indicator
class is defined so that the opacity of any element with this class is 0 by default, making it invisible
but present in the DOM.
当 htmx 发出请求时,它会将 htmx-request
类放到元素上(如果指定,则是请求元素或另一个元素)。htmx-request
类将导致具有 htmx-indicator
类的子元素转换为不透明度 1,显示指示器。
¥When htmx issues a request, it will put a htmx-request
class onto an element (either the requesting element or
another element, if specified). The htmx-request
class will cause a child element with the htmx-indicator
class
on it to transition to an opacity of 1, showing the indicator.
<button hx-get="/click">
Click Me!
<img class="htmx-indicator" src="/spinner.gif">
</button>
这里我们有一个按钮。单击时,htmx-request
类将添加到其中,这将显示加载控件 gif 元素。(最近我喜欢 SVG 旋转器。)
¥Here we have a button. When it is clicked the htmx-request
class will be added to it, which will reveal the spinner
gif element. (I like SVG spinners these days.)
虽然 htmx-indicator
类使用不透明度来隐藏和显示进度指示器,但如果你更喜欢其他机制,你可以像这样创建自己的 CSS 转换:
¥While the htmx-indicator
class uses opacity to hide and show the progress indicator, if you would prefer another mechanism
you can create your own CSS transition like so:
.htmx-indicator{
display:none;
}
.htmx-request .htmx-indicator{
display:inline;
}
.htmx-request.htmx-indicator{
display:inline;
}
如果你希望将 htmx-request
类添加到不同的元素,可以使用 hx-indicator 属性和 CSS 选择器来实现:
¥If you want the htmx-request
class added to a different element, you can use the hx-indicator
attribute with a CSS selector to do so:
<div>
<button hx-get="/click" hx-indicator="#indicator">
Click Me!
</button>
<img id="indicator" class="htmx-indicator" src="/spinner.gif"/>
</div>
在这里,我们通过 id 明确调用指示器。请注意,我们也可以将类放在父 div
上并产生相同的效果。
¥Here we call out the indicator explicitly by id. Note that we could have placed the class on the parent div
as well
and had the same effect.
你还可以使用 hx-disabled-elt 属性将 disabled
属性 添加到元素中以持续请求。
¥You can also add the disabled
attribute to
elements for the duration of a request by using the hx-disabled-elt attribute.
¥Targets
如果你希望将响应加载到发出请求的元素以外的其他元素中,可以使用 hx-target 属性,该属性采用 CSS 选择器。回顾我们的实时搜索示例:
¥If you want the response to be loaded into a different element other than the one that made the request, you can use the hx-target attribute, which takes a CSS selector. Looking back at our Live Search example:
<input type="text" name="q"
hx-get="/trigger_delay"
hx-trigger="keyup delay:500ms changed"
hx-target="#search-results"
placeholder="Search...">
<div id="search-results"></div>
你可以看到搜索结果将被加载到 div#search-results
中,而不是加载到输入标签中。
¥You can see that the results from the search are going to be loaded into div#search-results
, rather than into the
input tag.
¥Extended CSS Selectors
hx-target
和大多数采用 CSS 选择器的属性都支持 “extended” CSS 语法:
¥hx-target
, and most attributes that take a CSS selector, support an “extended” CSS syntax:
你可以使用 this
关键字,它表示 hx-target
属性所在的元素是目标
¥You can use the this
keyword, which indicates that the element that the hx-target
attribute is on is the target
closest <CSS selector>
语法将查找与给定 CSS 选择器匹配的 closest 祖级元素或其本身。(例如 closest tr
将定位到距离元素最近的表格行)
¥The closest <CSS selector>
syntax will find the closest
ancestor element or itself, that matches the given CSS selector.
(e.g. closest tr
will target the closest table row to the element)
next <CSS selector>
语法将查找与给定 CSS 选择器匹配的 DOM 中的下一个元素。
¥The next <CSS selector>
syntax will find the next element in the DOM matching the given CSS selector.
previous <CSS selector>
语法将查找与给定 CSS 选择器匹配的 DOM 中的前一个元素。
¥The previous <CSS selector>
syntax will find the previous element in the DOM matching the given CSS selector.
find <CSS selector>
将查找与给定 CSS 选择器匹配的第一个子后代元素。(例如 find tr
将定位元素的第一个子后代行)
¥find <CSS selector>
which will find the first child descendant element that matches the given CSS selector.
(e.g find tr
would target the first child descendant row to the element)
此外,CSS 选择器可以封装在 <
和 />
字符中,模仿超脚本的 查询字面量 语法。
¥In addition, a CSS selector may be wrapped in <
and />
characters, mimicking the
query literal syntax of hyperscript.
像这样的相对目标对于创建灵活的用户界面非常有用,而无需在 DOM 上添加大量 id
属性。
¥Relative targets like this can be useful for creating flexible user interfaces without peppering your DOM with lots
of id
attributes.
¥Swapping
htmx 提供了几种不同的方法来交换返回到 DOM 中的 HTML。默认情况下,内容将替换目标元素的 innerHTML
。你可以使用 hx-swap 属性和以下任意值来修改它:
¥htmx offers a few different ways to swap the HTML returned into the DOM. By default, the content replaces the
innerHTML
of the target element. You can modify this by using the hx-swap attribute
with any of the following values:
名称 | 描述 |
---|---|
innerHTML | 默认情况下,将内容放入目标元素内 |
outerHTML | 用返回的内容替换整个目标元素 |
afterbegin | 在目标中的第一个子元素之前添加内容 |
beforebegin | 在目标的父元素中在目标之前添加内容 |
beforeend | 将内容附加到目标内的最后一个子元素之后 |
afterend | 将内容附加到目标父元素中的目标之后 |
delete | 无论响应如何,都删除目标元素 |
none | 不附加响应内容(带外交换 和 响应标头 仍将被处理) |
¥Morph Swaps
除了上述标准交换机制外,htmx 还通过扩展支持变形交换。变形交换尝试将新内容合并到现有 DOM 中,而不是简单地替换它。它们通常通过在交换操作期间就地改变现有节点来更好地保留焦点、视频状态等内容,但代价是更多的 CPU。
¥In addition to the standard swap mechanisms above, htmx also supports morphing swaps, via extensions. Morphing swaps attempt to merge new content into the existing DOM, rather than simply replacing it. They often do a better job preserving things like focus, video state, etc. by mutating existing nodes in-place during the swap operation, at the cost of more CPU.
以下扩展可用于变形样式交换:
¥The following extensions are available for morph-style swaps:
Idiomorph - 由 htmx 开发者创建的变形算法。
¥Idiomorph - A morphing algorithm created by the htmx developers.
形态域交换 - 基于 morphdom,原始 DOM 变形库。
¥Morphdom Swap - Based on the morphdom, the original DOM morphing library.
Alpine-morph - 基于 高山变形 插件,与 alpine.js 配合良好
¥Alpine-morph - Based on the alpine morph plugin, plays well with alpine.js
¥View Transitions
新的实验性 查看转换 API 为开发者提供了一种在不同 DOM 状态之间创建动画过渡的方法。它仍处于积极开发阶段,并非在所有浏览器中都可用,但 htmx 提供了一种使用此新 API 的方法,如果给定浏览器中没有该 API,则返回到非转换机制。
¥The new, experimental View Transitions API gives developers a way to create an animated transition between different DOM states. It is still in active development and is not available in all browsers, but htmx provides a way to work with this new API that falls back to the non-transition mechanism if the API is not available in a given browser.
你可以使用以下方法试验这个新 API:
¥You can experiment with this new API using the following approaches:
将 htmx.config.globalViewTransitions
配置变量设置为 true
以对所有交换使用转换
¥Set the htmx.config.globalViewTransitions
config variable to true
to use transitions for all swaps
在 hx-swap
属性中使用 transition:true
选项
¥Use the transition:true
option in the hx-swap
attribute
如果由于上述任一配置而将转换元素交换,你可以捕获 htmx:beforeTransition
事件并对其调用 preventDefault()
以取消转换。
¥If an element swap is going to be transitioned due to either of the above configurations, you may catch the
htmx:beforeTransition
event and call preventDefault()
on it to cancel the transition.
可以使用 CSS 配置视图转换,如 该功能的 Chrome 文档 中所述。
¥View Transitions can be configured using CSS, as outlined in the Chrome documentation for the feature.
你可以在 动画示例 页面上看到视图转换示例。
¥You can see a view transition example on the Animation Examples page.
¥Swap Options
hx-swap 属性支持许多用于调整 htmx 交换行为的选项。例如,默认情况下,htmx 会交换在新内容中任何地方找到的标题标签的标题。你可以通过将 ignoreTitle
修饰符设置为 true 来关闭此行为:
¥The hx-swap attribute supports many options for tuning the swapping behavior of htmx. For
example, by default htmx will swap in the title of a title tag found anywhere in the new content. You can turn this
behavior off by setting the ignoreTitle
modifier to true:
<button hx-post="/like" hx-swap="outerHTML ignoreTitle:true">Like</button>
hx-swap
上可用的修饰符是:
¥The modifiers available on hx-swap
are:
选项 | 描述 |
---|---|
transition | true 或 false ,是否使用视图转换 API 进行此交换 |
swap | 清除旧内容和插入新内容之间的交换延迟(例如 100ms ) |
settle | 插入新内容和新内容稳定之间的稳定延迟(例如 100ms ) |
ignoreTitle | 如果设置为 true ,则新内容中找到的任何标题都将被忽略,并且不会更新文档标题 |
scroll | top 或 bottom ,将目标元素滚动到其顶部或底部 |
show | top 或 bottom ,将目标元素的顶部或底部滚动到视图中 |
所有交换修饰符在指定交换样式后出现,并以冒号分隔。
¥All swap modifiers appear after the swap style is specified, and are colon-separated.
有关这些选项的更多详细信息,请参阅 hx-swap 文档。
¥See the hx-swap documentation for more details on these options.
¥Synchronization
你通常希望协调两个元素之间的请求。例如,你可能希望一个元素的请求取代另一个元素的请求,或者等到另一个元素的请求完成。
¥Often you want to coordinate the requests between two elements. For example, you may want a request from one element to supersede the request of another element, or to wait until the other element’s request has finished.
htmx 提供 hx-sync
属性来帮助你实现这一点。
¥htmx offers a hx-sync
attribute to help you accomplish this.
考虑此 HTML 中表单提交和单个输入的验证请求之间的竞争条件:
¥Consider a race condition between a form submission and an individual input’s validation request in this HTML:
<form hx-post="/store">
<input id="title" name="title" type="text"
hx-post="/validate"
hx-trigger="change">
<button type="submit">Submit</button>
</form>
如果不使用 hx-sync
,填写输入并立即提交表单会触发对 /validate
和 /store
的两个并行请求。
¥Without using hx-sync
, filling out the input and immediately submitting the form triggers two parallel requests to
/validate
and /store
.
在输入上使用 hx-sync="closest form:abort"
将监视表单上的请求,如果存在表单请求或在输入请求进行时启动,则中止输入的请求:
¥Using hx-sync="closest form:abort"
on the input will watch for requests on the form and abort the input’s request if
a form request is present or starts while the input request is in flight:
<form hx-post="/store">
<input id="title" name="title" type="text"
hx-post="/validate"
hx-trigger="change"
hx-sync="closest form:abort">
<button type="submit">Submit</button>
</form>
这以声明的方式解决了两个元素之间的同步问题。
¥This resolves the synchronization between the two elements in a declarative way.
htmx 还支持以编程方式取消请求:你可以将 htmx:abort
事件发送到元素以取消任何正在进行的请求:
¥htmx also supports a programmatic way to cancel requests: you can send the htmx:abort
event to an element to
cancel any in-flight requests:
<button id="request-button" hx-post="/example">
Issue Request
</button>
<button onclick="htmx.trigger('#request-button', 'htmx:abort')">
Cancel Request
</button>
可以在 hx-sync
属性页面。 上找到更多示例和详细信息
¥More examples and details can be found on the hx-sync
attribute page.
¥CSS Transitions
htmx 使无需 javascript 即可轻松使用 CSS 转换。考虑此 HTML 内容:
¥htmx makes it easy to use CSS Transitions without javascript. Consider this HTML content:
<div id="div1">Original Content</div>
想象一下,此内容通过 ajax 请求被 htmx 替换为以下新内容:
¥Imagine this content is replaced by htmx via an ajax request with this new content:
<div id="div1" class="red">New Content</div>
注意两点:
¥Note two things:
div 在原始内容和新内容中具有相同的 id
¥The div has the same id in the original and in the new content
red
类已添加到新内容中
¥The red
class has been added to the new content
鉴于这种情况,我们可以编写从旧状态到新状态的 CSS 转换:
¥Given this situation, we can write a CSS transition from the old state to the new state:
.red {
color: red;
transition: all ease-in 1s ;
}
当 htmx 交换此新内容时,它会以 CSS 转换应用于新内容的方式进行,从而为你提供到新状态的流畅过渡。
¥When htmx swaps in this new content, it will do so in such a way that the CSS transition will apply to the new content, giving you a nice, smooth transition to the new state.
因此,总而言之,要对元素使用 CSS 转换,你需要做的就是保持其 id
在请求之间稳定!
¥So, in summary, all you need to do to use CSS transitions for an element is keep its id
stable across requests!
你可以查看 动画示例 以了解更多详细信息和现场演示。
¥You can see the Animation Examples for more details and live demonstrations.
¥Details
要了解 CSS 转换在 htmx 中实际上是如何工作的,你必须了解 htmx 使用的底层交换和结算模型。
¥To understand how CSS transitions actually work in htmx, you must understand the underlying swap & settle model that htmx uses.
当从服务器接收到新内容时,在交换内容之前,会检查页面的现有内容中是否存在与 id
属性匹配的元素。如果在新内容中找到与元素匹配的元素,则在交换发生之前将旧内容的属性复制到新元素上。然后交换新内容,但使用旧属性值。最后,在 “settle” 延迟(默认为 20 毫秒)后,新的属性值被交换进来。有点疯狂,但这就是允许 CSS 转换在开发者无需任何 javascript 的情况下工作的原因。
¥When new content is received from a server, before the content is swapped in, the existing
content of the page is examined for elements that match by the id
attribute. If a match
is found for an element in the new content, the attributes of the old content are copied
onto the new element before the swap occurs. The new content is then swapped in, but with the
old attribute values. Finally, the new attribute values are swapped in, after a “settle” delay
(20ms by default). A little crazy, but this is what allows CSS transitions to work without any javascript by
the developer.
¥Out of Band Swaps
如果你想要使用 id
属性将响应中的内容直接交换到 DOM 中,则可以在响应 html 中使用 hx-swap-oob 属性:
¥If you want to swap content from a response directly into the DOM by using the id
attribute you can use the
hx-swap-oob attribute in the response html:
<div id="message" hx-swap-oob="true">Swap me directly!</div>
Additional Content
在此响应中,div#message
将直接交换到匹配的 DOM 元素中,而其他内容将以正常方式交换到目标中。
¥In this response, div#message
would be swapped directly into the matching DOM element, while the additional content
would be swapped into the target in the normal manner.
你可以使用此技术对其他请求进行 “piggy-back” 更新。
¥You can use this technique to “piggy-back” updates on other requests.
¥Troublesome Tables
表格元素与带外交换结合使用时可能会出现问题,因为根据 HTML 规范,许多元素无法在 DOM 中独立存在(例如 <tr>
或 <td>
)。
¥Table elements can be problematic when combined with out of band swaps, because, by the HTML spec, many can’t stand on
their own in the DOM (e.g. <tr>
or <td>
).
为了避免这个问题,你可以使用 template
标签来封装这些元素:
¥To avoid this issue you can use a template
tag to encapsulate these elements:
<template>
<tr id="message" hx-swap-oob="true"><td>Joe</td><td>Smith</td></tr>
</template>
¥Selecting Content To Swap
如果你想选择响应 HTML 的子集以交换到目标,你可以使用 hx-select 属性,该属性采用 CSS 选择器并从响应中选择匹配的元素。
¥If you want to select a subset of the response HTML to swap into the target, you can use the hx-select attribute, which takes a CSS selector and selects the matching elements from the response.
你还可以使用 hx-select-oob 属性挑选出用于带外交换的内容片段,该属性采用元素 ID 列表来挑选和交换。
¥You can also pick out pieces of content for an out-of-band swap by using the hx-select-oob attribute, which takes a list of element IDs to pick out and swap.
¥Preserving Content During A Swap
如果你希望在交换过程中保留内容(例如,即使发生交换,你也希望继续播放视频播放器),你可以在希望保留的元素上使用 hx-preserve 属性。
¥If there is content that you wish to be preserved across swaps (e.g. a video player that you wish to remain playing even if a swap occurs) you can use the hx-preserve attribute on the elements you wish to be preserved.
¥Parameters
默认情况下,引发请求的元素将包含其值(如果有)。如果元素是表单,它将包含其中所有输入的值。
¥By default, an element that causes a request will include its value if it has one. If the element is a form it will include the values of all inputs within it.
与 HTML 表单一样,输入的 name
属性用作 htmx 发送的请求中的参数名称。
¥As with HTML forms, the name
attribute of the input is used as the parameter name in the request that htmx sends.
此外,如果元素导致非 GET
请求,则将包括最近的封闭表单的所有输入的值。
¥Additionally, if the element causes a non-GET
request, the values of all the inputs of the nearest enclosing form
will be included.
如果你希望包含其他元素的值,可以使用 hx-include 属性和 CSS 选择器来选择你想要在请求中包含其值的所有元素。
¥If you wish to include the values of other elements, you can use the hx-include attribute with a CSS selector of all the elements whose values you want to include in the request.
如果你希望过滤掉某些参数,可以使用 hx-params 属性。
¥If you wish to filter out some parameters you can use the hx-params attribute.
最后,如果你想以编程方式修改参数,可以使用 htmx:configRequest 事件。
¥Finally, if you want to programmatically modify the parameters, you can use the htmx:configRequest event.
¥File Upload
如果你希望通过 htmx 请求上传文件,可以将 hx-encoding 属性设置为 multipart/form-data
。这将使用 FormData
对象提交请求,该请求将正确地将文件包含在请求中。
¥If you wish to upload files via an htmx request, you can set the hx-encoding attribute to
multipart/form-data
. This will use a FormData
object to submit the request, which will properly include the file
in the request.
请注意,根据你的服务器端技术,你可能必须以非常不同的方式处理此类正文内容的请求。
¥Note that depending on your server-side technology, you may have to handle requests with this type of body content very differently.
请注意,htmx 会在上传过程中根据标准 progress
事件定期触发 htmx:xhr:progress
事件,你可以挂接到该事件以显示上传的进度。
¥Note that htmx fires a htmx:xhr:progress
event periodically based on the standard progress
event during upload,
which you can hook into to show the progress of the upload.
请参阅 示例部分 以获取更高级的形式模式,包括 进度条 和 错误处理。
¥See the examples section for more advanced form patterns, including progress bars and error handling.
¥Extra Values
你可以使用 hx-vals(JSON 格式的名称表达式对)和 hx-vars 属性(动态计算的逗号分隔的名称表达式对)在请求中包含额外值。
¥You can include extra values in a request using the hx-vals (name-expression pairs in JSON format) and hx-vars attributes (comma-separated name-expression pairs that are dynamically computed).
¥Confirming Requests
你通常希望在发出请求之前确认操作。htmx 支持 hx-confirm
属性,允许你使用简单的 javascript 对话框确认操作:
¥Often you will want to confirm an action before issuing a request. htmx supports the hx-confirm
attribute, which allows you to confirm an action using a simple javascript dialog:
<button hx-delete="/account" hx-confirm="Are you sure you wish to delete your account?">
Delete My Account
</button>
使用事件,你可以实现更复杂的确认对话框。确认示例 展示了如何使用 sweetalert2 库来确认 htmx 操作。
¥Using events you can implement more sophisticated confirmation dialogs. The confirm example shows how to use sweetalert2 library for confirmation of htmx actions.
¥Confirming Requests Using Events
另一个进行确认的选项是通过 htmx:confirm
事件。此事件在请求的每个触发器上触发(不仅仅是在具有 hx-confirm
属性的元素上),可用于实现请求的异步确认。
¥Another option to do confirmation with is via the htmx:confirm
event. This event
is fired on every trigger for a request (not just on elements that have a hx-confirm
attribute) and can be used
to implement asynchronous confirmation of the request.
以下是在任何具有 confirm-with-sweet-alert='true'
属性的元素上使用 甜蜜警报 的示例:
¥Here is an example using sweet alert on any element with a confirm-with-sweet-alert='true'
attribute on it:
document.body.addEventListener('htmx:confirm', function(evt) {
if (evt.target.matches("[confirm-with-sweet-alert='true']")) {
evt.preventDefault();
swal({
title: "Are you sure?",
text: "Are you sure you are sure?",
icon: "warning",
buttons: true,
dangerMode: true,
}).then((confirmed) => {
if (confirmed) {
evt.detail.issueRequest();
}
});
}
});
¥Attribute Inheritance
htmx 中的大多数属性都是继承的:它们适用于它们所在的元素以及任何子元素。这允许你将 “hoist” 属性添加到 DOM 中以避免代码重复。考虑以下 htmx:
¥Most attributes in htmx are inherited: they apply to the element they are on as well as any children elements. This allows you to “hoist” attributes up the DOM to avoid code duplication. Consider the following htmx:
<button hx-delete="/account" hx-confirm="Are you sure?">
Delete My Account
</button>
<button hx-put="/account" hx-confirm="Are you sure?">
Update My Account
</button>
这里我们有一个重复的 hx-confirm
属性。我们可以将此属性提升到父元素:
¥Here we have a duplicate hx-confirm
attribute. We can hoist this attribute to a parent element:
<div hx-confirm="Are you sure?">
<button hx-delete="/account">
Delete My Account
</button>
<button hx-put="/account">
Update My Account
</button>
</div>
此 hx-confirm
属性现在将应用于其中的所有 htmx 驱动元素。
¥This hx-confirm
attribute will now apply to all htmx-powered elements within it.
有时你希望撤消此继承。考虑如果我们有一个针对该组的取消按钮,但不想确认。我们可以像这样在其上添加 unset
指令:
¥Sometimes you wish to undo this inheritance. Consider if we had a cancel button to this group, but didn’t want it to
be confirmed. We could add an unset
directive on it like so:
<div hx-confirm="Are you sure?">
<button hx-delete="/account">
Delete My Account
</button>
<button hx-put="/account">
Update My Account
</button>
<button hx-confirm="unset" hx-get="/">
Cancel
</button>
</div>
然后,顶部的两个按钮将显示确认对话框,但底部的取消按钮不会显示。
¥The top two buttons would then show a confirm dialog, but the bottom cancel button would not.
可以使用 hx-disinherit
属性在每个元素和每个属性的基础上禁用继承。
¥Inheritance can be disabled on a per-element and per-attribute basis using the
hx-disinherit
attribute.
如果你希望完全禁用属性继承,可以将 htmx.config.disableInheritance
配置变量设置为 true
。这将默认禁用继承,并允许你使用 hx-inherit
属性明确指定继承。
¥If you wish to disable attribute inheritance entirely, you can set the htmx.config.disableInheritance
configuration
variable to true
. This will disable inheritance as a default, and allow you to specify inheritance explicitly
with the hx-inherit
attribute.
¥Boosting
Htmx 支持 “提升” 常规 HTML 锚点和具有 hx-boost 属性的表单。此属性会将所有锚标记和表单转换为 AJAX 请求,默认情况下,这些请求以页面主体为目标。
¥Htmx supports “boosting” regular HTML anchors and forms with the hx-boost attribute. This attribute will convert all anchor tags and forms into AJAX requests that, by default, target the body of the page.
这是一个例子:
¥Here is an example:
<div hx-boost="true">
<a href="/blog">Blog</a>
</div>
此 div 中的锚标记将向 /blog
发出 AJAX GET
请求,并将响应交换到 body
标记中。
¥The anchor tag in this div will issue an AJAX GET
request to /blog
and swap the response into the body
tag.
¥Progressive Enhancement
hx-boost
的一个特性是,如果未启用 javascript,它会优雅地降级:链接和表单继续工作,它们只是不使用 ajax 请求。这被称为 渐进式增强,它允许更广泛的受众使用你网站的功能。
¥A feature of hx-boost
is that it degrades gracefully if javascript is not enabled: the links and forms continue
to work, they simply don’t use ajax requests. This is known as
Progressive Enhancement, and it allows
a wider audience to use your site’s functionality.
其他 htmx 模式也可以适应以实现渐进式增强,但它们需要更多思考。
¥Other htmx patterns can be adapted to achieve progressive enhancement as well, but they will require more thought.
考虑 主动搜索 示例。正如所写的那样,它不会优雅地降级:未启用 javascript 的人将无法使用此功能。这样做是为了简单起见,使示例尽可能简短。
¥Consider the active search example. As it is written, it will not degrade gracefully: someone who does not have javascript enabled will not be able to use this feature. This is done for simplicity’s sake, to keep the example as brief as possible.
但是,你可以将 htmx 增强的输入封装在表单元素中:
¥However, you could wrap the htmx-enhanced input in a form element:
<form action="/search" method="POST">
<input class="form-control" type="search"
name="search" placeholder="Begin typing to search users..."
hx-post="/search"
hx-trigger="keyup changed delay:500ms, search"
hx-target="#search-results"
hx-indicator=".htmx-indicator">
</form>
使用此代码后,启用 javascript 的客户端仍将获得良好的主动搜索用户体验,但未启用 javascript 的客户端将能够按下回车键并继续搜索。更好的是,你还可以添加 “搜索” 按钮。然后,你需要使用镜像 action
属性的 hx-post
来更新表单,或者在其上使用 hx-boost
。
¥With this in place, javascript-enabled clients would still get the nice active-search UX, but non-javascript enabled
clients would be able to hit the enter key and still search. Even better, you could add a “Search” button as well.
You would then need to update the form with an hx-post
that mirrored the action
attribute, or perhaps use hx-boost
on it.
你需要在服务器端检查 HX-Request
标头以区分 htmx 驱动和常规请求,以确定要向客户端渲染什么。
¥You would need to check on the server side for the HX-Request
header to differentiate between an htmx-driven and a
regular request, to determine exactly what to render to the client.
可以类似地调整其他模式以实现应用的渐进增强需求。
¥Other patterns can be adapted similarly to achieve the progressive enhancement needs of your application.
如你所见,这需要更多的思考和工作。它还将某些功能完全排除在外。这些权衡必须由你(开发者)根据项目目标和受众做出。
¥As you can see, this requires more thought and more work. It also rules some functionality entirely out of bounds. These tradeoffs must be made by you, the developer, with respect to your projects goals and audience.
可访问性 是一个与渐进增强密切相关的概念。使用 hx-boost
等渐进式增强技术将使你的 htmx 应用更易于广泛用户访问。
¥Accessibility is a concept
closely related to progressive enhancement. Using progressive enhancement techniques such as hx-boost
will make your
htmx application more accessible to a wide array of users.
基于 htmx 的应用与普通的非 AJAX 驱动的 Web 应用非常相似,因为 htmx 是面向 HTML 的。
¥htmx-based applications are very similar to normal, non-AJAX driven web applications because htmx is HTML-oriented.
因此,适用正常的 HTML 可访问性建议。例如:
¥As such, the normal HTML accessibility recommendations apply. For example:
尽可能使用语义 HTML(即,为正确的事物使用正确的标签)
¥Use semantic HTML as much as possible (i.e. the right tags for the right things)
确保焦点状态清晰可见
¥Ensure focus state is clearly visible
将文本标签与所有表单字段关联
¥Associate text labels with all form fields
使用适当的字体、对比度等最大限度地提高应用的可读性。
¥Maximize the readability of your application with appropriate fonts, contrast, etc.
¥Web Sockets & SSE
通过扩展支持 Web 套接字和服务器发送事件 (SSE)。请参阅 SSE 扩展 和 WebSocket 扩展 页面了解更多信息。
¥Web Sockets and Server Sent Events (SSE) are supported via extensions. Please see the SSE extension and WebSocket extension pages to learn more.
¥History Support
Htmx 提供了一种与 浏览器历史记录 API 交互的简单机制:
¥Htmx provides a simple mechanism for interacting with the browser history API:
如果你希望给定元素将其请求 URL 推送到浏览器导航栏并将页面的当前状态添加到浏览器的历史记录中,请包含 hx-push-url 属性:
¥If you want a given element to push its request URL into the browser navigation bar and add the current state of the page to the browser’s history, include the hx-push-url attribute:
<a hx-get="/blog" hx-push-url="true">Blog</a>
当用户单击此链接时,htmx 将快照当前 DOM 并在向 /blog 发出请求之前将其存储。然后它进行交换并将新位置推送到历史堆栈上。
¥When a user clicks on this link, htmx will snapshot the current DOM and store it before it makes a request to /blog. It then does the swap and pushes a new location onto the history stack.
当用户点击后退按钮时,htmx 将从存储中检索旧内容并将其交换回目标,将 “返回” 模拟到之前的状态。如果在缓存中找不到该位置,htmx 将向给定的 URL 发出 ajax 请求,并将标头 HX-History-Restore-Request
设置为 true,并期望返回整个页面所需的 HTML。或者,如果将 htmx.config.refreshOnHistoryMiss
配置变量设置为 true,它将发出硬浏览器刷新。
¥When a user hits the back button, htmx will retrieve the old content from storage and swap it back into the target,
simulating “going back” to the previous state. If the location is not found in the cache, htmx will make an ajax
request to the given URL, with the header HX-History-Restore-Request
set to true, and expects back the HTML needed
for the entire page. Alternatively, if the htmx.config.refreshOnHistoryMiss
config variable is set to true, it will
issue a hard browser refresh.
注意:如果你将 URL 推送到历史记录中,你必须能够导航到该 URL 并返回完整页面!用户可以将 URL 复制并粘贴到电子邮件或新选项卡中。此外,如果页面不在历史记录缓存中,则 htmx 在恢复历史记录时将需要整个页面。
¥NOTE: If you push a URL into the history, you must be able to navigate to that URL and get a full page back! A user could copy and paste the URL into an email, or new tab. Additionally, htmx will need the entire page when restoring history if the page is not in the history cache.
¥Specifying History Snapshot Element
默认情况下,htmx 将使用 body
来获取和恢复历史快照。这通常是正确的,但如果你想使用更窄的元素进行快照,你可以使用 hx-history-elt 属性来指定不同的元素。
¥By default, htmx will use the body
to take and restore the history snapshot from. This is usually the right thing, but
if you want to use a narrower element for snapshotting you can use the hx-history-elt
attribute to specify a different one.
小心:此元素需要位于所有页面上,否则从历史记录中恢复将无法可靠地工作。
¥Careful: this element will need to be on all pages or restoring from history won’t work reliably.
¥Undoing DOM Mutations By 3rd Party Libraries
如果你正在使用第三方库并想要使用 htmx 历史记录功能,则需要在拍摄快照之前清理 DOM。让我们考虑 Tom 选择 库,它使选择元素的用户体验更加丰富。让我们设置 TomSelect 将任何具有 .tomselect
类的输入元素变成丰富的选择元素。
¥If you are using a 3rd party library and want to use the htmx history feature, you will need to clean up the DOM before
a snapshot is taken. Let’s consider the Tom Select library, which makes select elements
a much richer user experience. Let’s set up TomSelect to turn any input element with the .tomselect
class into a rich
select element.
首先,我们需要在新的内容中初始化具有该类的元素:
¥First we need to initialize elements that have the class in new content:
htmx.onLoad(function (target) {
// find all elements in the new content that should be
// an editor and init w/ TomSelect
var editors = target.querySelectorAll(".tomselect")
.forEach(elt => new TomSelect(elt))
});
这将为所有具有 .tomselect
类的输入元素创建一个丰富的选择器。但是,它会改变 DOM,我们不希望将该改变保存到历史缓存中,因为当历史内容重新加载到屏幕时,TomSelect 将被重新初始化。
¥This will create a rich selector for all input elements that have the .tomselect
class on it. However, it mutates
the DOM and we don’t want that mutation saved to the history cache, since TomSelect will be reinitialized when the
history content is loaded back into the screen.
要处理这个问题,我们需要捕获 htmx:beforeHistorySave
事件并通过调用 destroy()
清除 TomSelect 突变:
¥To deal with this, we need to catch the htmx:beforeHistorySave
event and clean out the TomSelect mutations by calling
destroy()
on them:
htmx.on('htmx:beforeHistorySave', function() {
// find all TomSelect elements
document.querySelectorAll('.tomSelect')
.forEach(elt => elt.tomselect.destroy()) // and call destroy() on them
})
这将使 DOM 恢复为原始 HTML,从而允许干净的快照。
¥This will revert the DOM to the original HTML, thus allowing for a clean snapshot.
¥Disabling History Snapshots
可以通过将当前文档中任何元素的 hx-history 属性设置为 false
,或通过 htmx 加载到当前文档中的任何 html 片段,为 URL 禁用历史快照。这可用于防止敏感数据进入 localStorage 缓存,这对于共享使用/公共计算机非常重要。历史导航将按预期工作,但在恢复时,将从服务器而不是本地历史缓存请求 URL。
¥History snapshotting can be disabled for a URL by setting the hx-history attribute to false
on any element in the current document, or any html fragment loaded into the current document by htmx. This can be used
to prevent sensitive data entering the localStorage cache, which can be important for shared-use / public computers.
History navigation will work as expected, but on restoration the URL will be requested from the server instead of the
local history cache.
¥Requests & Responses
Htmx 期望它发出的 AJAX 请求的响应是 HTML,通常是 HTML 片段(尽管与 hx-select 标记匹配的完整 HTML 文档也很有用)。Htmx 随后将使用指定的交换策略将返回的 HTML 交换到指定目标处的文档中。
¥Htmx expects responses to the AJAX requests it makes to be HTML, typically HTML fragments (although a full HTML document, matched with a hx-select tag can be useful too). Htmx will then swap the returned HTML into the document at the target specified and with the swap strategy specified.
有时你可能不想在交换中执行任何操作,但仍可能触发客户端事件 (见下文)。
¥Sometimes you might want to do nothing in the swap, but still perhaps trigger a client side event (see below).
对于这种情况,默认情况下,你可以返回 204 - No Content
响应代码,htmx 将忽略响应的内容。
¥For this situation, by default, you can return a 204 - No Content
response code, and htmx will ignore the content of
the response.
如果服务器响应错误(例如 404 或 501),htmx 将触发 htmx:responseError
事件,你可以处理该事件。
¥In the event of an error response from the server (e.g. a 404 or a 501), htmx will trigger the htmx:responseError
event, which you can handle.
如果发生连接错误,将触发 htmx:sendError
事件。
¥In the event of a connection error, the htmx:sendError
event will be triggered.
¥Configuring Response Handling
你可以通过改变或替换 htmx.config.responseHandling
数组来配置 htmx 的上述行为。此对象是 JavaScript 对象的集合,定义如下:
¥You can configure the above behavior of htmx by mutating or replacing the htmx.config.responseHandling
array. This
object is a collection of JavaScript objects defined like so:
responseHandling: [
{code:"204", swap: false}, // 204 - No Content by default does nothing, but is not an error
{code:"[23]..", swap: true}, // 200 & 300 responses are non-errors and are swapped
{code:"[45]..", swap: false, error:true}, // 400 & 500 responses are not swapped and are errors
{code:"...", swap: false} // catch all for any other response code
]
当 htmx 收到响应时,它会按顺序遍历 htmx.config.responseHandling
数组并测试给定对象的 code
属性(当将其视为正则表达式时)是否与当前响应匹配。如果条目与当前响应代码匹配,它将用于确定是否以及如何处理响应。
¥When htmx receives a response it will iterate in order over the htmx.config.responseHandling
array and test if the
code
property of a given object, when treated as a Regular Expression, matches the current response. If an entry
does match the current response code, it will be used to determine if and how the response will be processed.
此数组中条目的响应处理配置可用的字段为:
¥The fields available for response handling configuration on entries in this array are:
code
- 表示将针对响应代码进行测试的正则表达式的字符串。
¥code
- a String representing a regular expression that will be tested against response codes.
swap
- 如果响应应交换到 DOM,则为 true
,否则为 false
¥swap
- true
if the response should be swapped into the DOM, false
otherwise
error
- 如果 htmx 应将此响应视为错误,则为 true
¥error
- true
if htmx should treat this response as an error
ignoreTitle
- 如果 htmx 应忽略响应中的标题标签,则为 true
¥ignoreTitle
- true
if htmx should ignore title tags in the response
select
- 用于从响应中选择内容的 CSS 选择器
¥select
- A CSS selector to use to select content from the response
target
- 指定响应的替代目标的 CSS 选择器
¥target
- A CSS selector specifying an alternative target for the response
swapOverride
- 响应的替代交换机制
¥swapOverride
- An alternative swap mechanism for the response
¥Configuring Response Handling Examples
作为如何使用此配置的示例,考虑当发生验证错误时服务器端框架以 422 - Unprocessable Entity
响应进行响应的情况。默认情况下,htmx 将忽略响应,因为它与正则表达式 [45]..
匹配。
¥As an example of how to use this configuration, consider a situation when a server-side framework responds with a
422 - Unprocessable Entity
response when validation errors occur. By default, htmx will ignore the response,
since it matches the Regular Expression [45]..
.
使用 meta 配置 机制配置 responseHandling,我们可以添加以下配置:
¥Using the meta config mechanism for configuring responseHandling, we could add the following config:
<!--
* 204 No Content by default does nothing, but is not an error
* 2xx, 3xx and 422 responses are non-errors and are swapped
* 4xx & 5xx responses are not swapped and are errors
* all other responses are swapped using "..." as a catch-all
-->
<meta
name="htmx-config"
content='{
"responseHandling":[
{"code":"204", "swap": false},
{"code":"[23]..", "swap": true},
{"code":"422", "swap": true},
{"code":"[45]..", "swap": false, "error":true},
{"code":"...", "swap": true}
]
}'
/>
如果你想要交换所有内容,而不管 HTTP 响应代码如何,都可以使用此配置:
¥If you wanted to swap everything, regardless of HTTP response code, you could use this configuration:
<meta name="htmx-config" content='{"responseHandling": [{"code":".*", "swap": true}]}' /> <!--all responses are swapped-->
最后,值得考虑使用 响应目标 扩展,它允许你通过属性声明性地配置响应代码的行为。
¥Finally, it is worth considering using the Response Targets extension, which allows you to configure the behavior of response codes declaratively via attributes.
在跨源上下文中使用 htmx 时,请记住配置你的 Web 服务器以设置 Access-Control 标头,以便 htmx 标头在客户端可见。
¥When using htmx in a cross origin context, remember to configure your web server to set Access-Control headers in order for htmx headers to be visible on the client side.
¥See all the request and response headers that htmx implements.
¥Request Headers
htmx 在请求中包含了许多有用的标头:
¥htmx includes a number of useful headers in requests:
标题 | 描述 |
---|---|
HX-Boosted | 表示请求是通过使用 hx-boost 的元素进行的 |
HX-Current-URL | 浏览器的当前 URL |
HX-History-Restore-Request | 如果请求是在本地历史缓存中未命中后进行历史恢复,则为 “true” |
HX-Prompt | 用户对 hx-prompt 的响应 |
HX-Request | 始终为 “true” |
HX-Target | 如果存在,则为目标元素的 id |
HX-Trigger-Name | 如果存在,则为触发元素的 name |
HX-Trigger | 如果存在,则为触发元素的 id |
¥Response Headers
htmx 支持一些 htmx 特定的响应标头:
¥htmx supports some htmx-specific response headers:
HX-Location
- 允许你执行不执行完整页面重新加载的客户端重定向
¥HX-Location
- allows you to do a client-side redirect that does not do a full page reload
HX-Push-Url
- 将新 URL 推送到历史记录堆栈
¥HX-Push-Url
- pushes a new url into the history stack
HX-Redirect
- 可用于将客户端重定向到新位置
¥HX-Redirect
- can be used to do a client-side redirect to a new location
HX-Refresh
- 如果设置为 “true”,客户端将对页面进行完全刷新
¥HX-Refresh
- if set to “true” the client-side will do a full refresh of the page
HX-Replace-Url
- 替换位置栏中的当前 URL
¥HX-Replace-Url
- replaces the current URL in the location bar
HX-Reswap
- 允许你指定如何交换响应。有关可能的值,请参阅 hx-swap
¥HX-Reswap
- allows you to specify how the response will be swapped. See hx-swap for possible values
HX-Retarget
- 将内容更新目标更新为页面上不同元素的 CSS 选择器
¥HX-Retarget
- a CSS selector that updates the target of the content update to a different element on the page
HX-Reselect
- 允许你选择使用响应的哪一部分进行交换的 CSS 选择器。覆盖触发元素上的现有 hx-select
¥HX-Reselect
- a CSS selector that allows you to choose which part of the response is used to be swapped in. Overrides an existing hx-select
on the triggering element
HX-Trigger
- 允许你触发客户端事件
¥HX-Trigger
- allows you to trigger client-side events
HX-Trigger-After-Settle
- 允许你在解决步骤后触发客户端事件
¥HX-Trigger-After-Settle
- allows you to trigger client-side events after the settle step
HX-Trigger-After-Swap
- 允许你在交换步骤后触发客户端事件
¥HX-Trigger-After-Swap
- allows you to trigger client-side events after the swap step
有关 HX-Trigger
标头的更多信息,请参阅 HX-Trigger
响应标头。
¥For more on the HX-Trigger
headers, see HX-Trigger
Response Headers.
通过 htmx 提交表单的好处是不再需要 Post/Redirect/Get 模式。在服务器上成功处理 POST 请求后,你不需要返回 HTTP 302 (重定向)。你可以直接返回新的 HTML 片段。
¥Submitting a form via htmx has the benefit of no longer needing the Post/Redirect/Get Pattern. After successfully processing a POST request on the server, you don’t need to return a HTTP 302 (Redirect). You can directly return the new HTML fragment.
此外,上述响应标头不提供给 htmx 以使用 3xx 重定向响应代码(如 HTTP 302 (重定向))进行处理。相反,浏览器将在内部拦截重定向并从重定向的 URL 返回标头和响应。尽可能使用替代响应代码(如 200)来允许返回这些响应标头。
¥Also the response headers above are not provided to htmx for processing with 3xx Redirect response codes like HTTP 302 (Redirect). Instead, the browser will intercept the redirection internally and return the headers and response from the redirected URL. Where possible use alternative response codes like 200 to allow returning of these response headers.
¥Request Order of Operations
htmx 请求中的操作顺序为:
¥The order of operations in a htmx request are:
元素被触发并开始请求
¥The element is triggered and begins a request
为请求收集值
¥Values are gathered for the request
htmx-request
类应用于适当的元素
¥The htmx-request
class is applied to the appropriate elements
然后通过 AJAX 异步发出请求
¥The request is then issued asynchronously via AJAX
获得响应后,目标元素将标记为 htmx-swapping
类
¥Upon getting a response the target element is marked with the htmx-swapping
class
应用了可选的交换延迟(参见 hx-swap 属性)
¥An optional swap delay is applied (see the hx-swap attribute)
实际内容交换已完成
¥The actual content swap is done
htmx-swapping
类从目标中删除
¥the htmx-swapping
class is removed from the target
htmx-added
类添加到每个新内容
¥the htmx-added
class is added to each new piece of content
htmx-settling
类应用于目标
¥the htmx-settling
class is applied to the target
完成延迟(默认值:20ms)
¥A settle delay is done (default: 20ms)
DOM 已确定
¥The DOM is settled
htmx-settling
类从目标中删除
¥the htmx-settling
class is removed from the target
htmx-added
类从每个新内容中删除
¥the htmx-added
class is removed from each new piece of content
你可以使用 htmx-swapping
和 htmx-settling
类在页面之间创建 CSS 转换。
¥You can use the htmx-swapping
and htmx-settling
classes to create
CSS transitions between pages.
¥Validation
Htmx 与 HTML5 验证 API 集成,如果可验证输入无效,则不会发出表单请求。这对于 AJAX 请求和 WebSocket 发送都是如此。
¥Htmx integrates with the HTML5 Validation API and will not issue a request for a form if a validatable input is invalid. This is true for both AJAX requests as well as WebSocket sends.
Htmx 围绕验证触发事件,可用于挂接自定义验证和错误处理:
¥Htmx fires events around validation that can be used to hook in custom validation and error handling:
htmx:validation:validate
- 在调用元素的 checkValidity()
方法之前调用。可用于添加自定义验证逻辑
¥htmx:validation:validate
- called before an element’s checkValidity()
method is called. May be used to add in
custom validation logic
htmx:validation:failed
- 当 checkValidity()
返回 false 时调用,表示输入无效
¥htmx:validation:failed
- called when checkValidity()
returns false, indicating an invalid input
htmx:validation:halted
- 由于验证错误而未发出请求时调用。可以在 event.detail.errors
对象中找到特定错误
¥htmx:validation:halted
- called when a request is not issued due to validation errors. Specific errors may be found
in the event.detail.errors
object
默认情况下,非表单元素在发出请求之前不会进行验证,但你可以通过将 hx-validate
属性设置为 “true” 来启用验证。
¥Non-form elements do not validate before they make requests by default, but you can enable validation by setting
the hx-validate
attribute to “true”.
¥Validation Example
以下是使用 hx-on
属性捕获 htmx:validation:validate
事件并要求输入具有值 foo
的输入的示例:
¥Here is an example of an input that uses the hx-on
attribute to catch the
htmx:validation:validate
event and require that the input have the value foo
:
<form id="example-form" hx-post="/test">
<input name="example"
onkeyup="this.setCustomValidity('') // reset the validation on keyup"
hx-on:htmx:validation:validate="if(this.value != 'foo') {
this.setCustomValidity('Please enter the value foo') // set the validation error
htmx.find('#example-form').reportValidity() // report the issue
}">
</form>
请注意,所有客户端验证都必须在服务器端重新完成,因为它们总是可以被绕过。
¥Note that all client side validations must be re-done on the server side, as they can always be bypassed.
¥Animations
Htmx 允许你在许多情况下仅使用 HTML 和 CSS 使用 CSS 转换。
¥Htmx allows you to use CSS transitions in many situations using only HTML and CSS.
有关可用选项的更多详细信息,请参阅 动画指南。
¥Please see the Animation Guide for more details on the options available.
¥Extensions
htmx 提供了一种 扩展 机制,允许你自定义库的行为。扩展 在 javascript 中定义,然后通过 hx-ext
属性启用。
¥htmx provides an extensions mechanism that allows you to customize the libraries’ behavior.
Extensions are defined in javascript and then enabled via
the hx-ext
attribute.
¥Core Extensions
htmx 支持一些 “core” 扩展,这些扩展由 htmx 开发团队支持:
¥htmx supports a few “core” extensions, which are supported by the htmx development team:
head-support - 支持在 htmx 请求中合并 head 标签信息(样式等)
¥head-support - support for merging head tag information (styles, etc.) in htmx requests
htmx-1-compat - 恢复 htmx 1 默认值和功能
¥htmx-1-compat - restores htmx 1 defaults & functionality
idiomorph - 使用 idiomorph 支持 morph
交换策略
¥idiomorph - supports the morph
swap strategy using idiomorph
preload - 允许你预加载内容以获得更好的性能
¥preload - allows you to preload content for better performance
response-targets - 允许你根据 HTTP 响应代码(例如 404
)定位元素
¥response-targets - allows you to target elements based on HTTP response codes (e.g. 404
)
¥sse - support for Server Sent Events
¥ws - support for Web Sockets
你可以在 扩展 页面上看到所有可用的扩展。
¥You can see all available extensions on the Extensions page.
¥Installing Extensions
安装其他人创建的 htmx 扩展的最快方法是通过 CDN 加载它们。请记住始终在扩展和 启用扩展 之前包含核心 htmx 库。例如,如果你想使用 response-targets 扩展,则可以将其添加到 head 标签中:
¥The fastest way to install htmx extensions created by others is to load them via a CDN. Remember to always include the core htmx library before the extensions and enable the extension. For example, if you would like to use the response-targets extension, you can add this to your head tag:
<head>
<script src="https://unpkg.com/htmx.org@2.0.4" integrity="sha384-HGfztofotfshcF7+8n44JQL2oJmowVChPTg48S+jvZoztPfvwD79OC/LTtG6dMp+" crossorigin="anonymous"></script>
<script src="https://unpkg.com/htmx-ext-response-targets@2.0.2" integrity="sha384-T41oglUPvXLGBVyRdZsVRxNWnOOqCynaPubjUVjxhsjFTKrFJGEMm3/0KGmNQ+Pg" crossorigin="anonymous"></script>
</head>
<body hx-ext="extension-name">
...
https://unpkg.com/htmx-ext-extension-name/dist/extension-name.js
上还有一个未缩小的版本(将 extension-name
替换为扩展名)。
¥An unminified version is also available at https://unpkg.com/htmx-ext-extension-name/dist/extension-name.js
(replace extension-name
with the name of the extension).
虽然 CDN 方法很简单,但你可能需要考虑 在生产中不使用 CDN。安装 htmx 扩展的下一个最简单的方法是将其复制到你的项目中。从 https://unpkg.com/htmx-ext-extension-name
下载扩展(将 extension-name
替换为扩展名),例如 https://unpkg.com/htmx-ext-response-targets。然后将其添加到项目中的相应目录中,并在必要时使用 <script>
标签包含它。
¥While the CDN approach is simple, you may want to consider not using CDNs in production. The next easiest way to install htmx extensions is to simply copy them into your project. Download the extension from https://unpkg.com/htmx-ext-extension-name
(replace extension-name
with the name of the extension) e.g., https://unpkg.com/htmx-ext-response-targets. Then add it to the appropriate directory in your project and include it where necessary with a <script>
tag.
对于 npm 样式的构建系统,你可以通过 npm 安装 htmx 扩展(将 extension-name
替换为扩展名):
¥For npm-style build systems, you can install htmx extensions via npm (replace extension-name
with the name of the extension):
npm install htmx-ext-extension-name
安装后,你需要使用适当的工具来打包 node_modules/htmx-ext-extension-name/dist/extension-name.js
(或 .min.js
)。例如,你可以将扩展与来自 node_modules/htmx.org/dist/htmx.js
的 htmx 核心和项目特定代码打包在一起。
¥After installing, you’ll need to use appropriate tooling to bundle node_modules/htmx-ext-extension-name/dist/extension-name.js
(or .min.js
). For example, you might bundle the extension with htmx core from node_modules/htmx.org/dist/htmx.js
and project-specific code.
如果你使用打包器来管理你的 javascript(例如 Webpack、Rollup):
¥If you are using a bundler to manage your javascript (e.g. Webpack, Rollup):
通过 npm 安装 htmx.org
和 htmx-ext-extension-name
(将 extension-name
替换为扩展的名称)
¥Install htmx.org
and htmx-ext-extension-name
via npm (replace extension-name
with the name of the extension)
将两个包导入到你的 index.js
¥Import both packages to your index.js
import `htmx.org`;
import `htmx-ext-extension-name`; // replace `extension-name` with the name of the extension
注意:Idiomorph 不遵循 htmx 扩展的命名约定。使用 idiomorph
代替 htmx-ext-idiomorph
。例如,https://unpkg.com/idiomorph
或 npm install idiomorph
。
¥Note: Idiomorph does not follow the naming convention of htmx extensions. Use idiomorph
instead of htmx-ext-idiomorph
. For example, https://unpkg.com/idiomorph
or npm install idiomorph
.
注意:托管在此存储库之外的社区扩展可能有不同的安装说明。请查看相应的存储库以获取设置指南。
¥Note: Community extensions hosted outside this repository might have different installation instructions. Please check the corresponding repository for set-up guidance.
¥Enabling Extensions
要启用扩展,请将 hx-ext="extension-name"
属性添加到 <body>
或另一个 HTML 元素(将 extension-name
替换为扩展的名称)。扩展将应用于所有子元素。
¥To enable an extension, add a hx-ext="extension-name"
attribute to <body>
or another HTML element (replace extension-name
with the name of the extension). The extension will be applied to all child elements.
以下示例显示如何启用 response-targets 扩展,允许你根据 HTTP 响应代码指定要交换的不同目标元素。
¥The following example shows how to enable response-targets extension, allowing you to specify different target elements to be swapped based on HTTP response code.
<body hx-ext="response-targets">
...
<button hx-post="/register" hx-target="#response-div" hx-target-404="#not-found">
Register!
</button>
<div id="response-div"></div>
<div id="not-found"></div>
...
</body>
¥Creating Extensions
如果你有兴趣将自己的扩展添加到 htmx,请使用 查看扩展文档。
¥If you are interested in adding your own extension to htmx, please see the extension docs.
¥Events & Logging
Htmx 有一个广泛的 事件机制,它兼作日志系统。
¥Htmx has an extensive events mechanism, which doubles as the logging system.
如果你想注册给定的 htmx 事件,你可以使用
¥If you want to register for a given htmx event you can use
document.body.addEventListener('htmx:load', function(evt) {
myJavascriptLib.init(evt.detail.elt);
});
或者,如果你愿意,你可以使用以下 htmx 辅助程序:
¥or, if you would prefer, you can use the following htmx helper:
htmx.on("htmx:load", function(evt) {
myJavascriptLib.init(evt.detail.elt);
});
每次 htmx 将元素加载到 DOM 中时,都会触发 htmx:load
事件,实际上相当于普通的 load
事件。
¥The htmx:load
event is fired every time an element is loaded into the DOM by htmx, and is effectively the equivalent
to the normal load
event.
htmx 事件的一些常见用途是:
¥Some common uses for htmx events are:
¥Initialize A 3rd Party Library With Events
使用 htmx:load
事件初始化内容非常常见,因此 htmx 提供了一个辅助函数:
¥Using the htmx:load
event to initialize content is so common that htmx provides a helper function:
htmx.onLoad(function(target) {
myJavascriptLib.init(target);
});
这与第一个例子的作用相同,但更简洁一些。
¥This does the same thing as the first example, but is a little cleaner.
¥Configure a Request With Events
你可以处理 htmx:configRequest
事件以在发出 AJAX 请求之前对其进行修改:
¥You can handle the htmx:configRequest
event in order to modify an AJAX request before it is issued:
document.body.addEventListener('htmx:configRequest', function(evt) {
evt.detail.parameters['auth_token'] = getAuthToken(); // add a new parameter into the request
evt.detail.headers['Authentication-Token'] = getAuthToken(); // add a new header into the request
});
在这里,我们在发送请求之前添加了一个参数和标头。
¥Here we add a parameter and header to the request before it is sent.
¥Modifying Swapping Behavior With Events
你可以处理 htmx:beforeSwap
事件以修改 htmx 的交换行为:
¥You can handle the htmx:beforeSwap
event in order to modify the swap behavior of htmx:
document.body.addEventListener('htmx:beforeSwap', function(evt) {
if(evt.detail.xhr.status === 404){
// alert the user when a 404 occurs (maybe use a nicer mechanism than alert())
alert("Error: Could Not Find Resource");
} else if(evt.detail.xhr.status === 422){
// allow 422 responses to swap as we are using this as a signal that
// a form was submitted with bad data and want to rerender with the
// errors
//
// set isError to false to avoid error logging in console
evt.detail.shouldSwap = true;
evt.detail.isError = false;
} else if(evt.detail.xhr.status === 418){
// if the response code 418 (I'm a teapot) is returned, retarget the
// content of the response to the element with the id `teapot`
evt.detail.shouldSwap = true;
evt.detail.target = htmx.find("#teapot");
}
});
在这里,我们处理一些通常不会在 htmx 中进行交换的 400 级错误响应代码。
¥Here we handle a few 400-level error response codes that would normally not do a swap in htmx.
¥Event Naming
请注意,所有事件都以两个不同的名称触发
¥Note that all events are fired with two different names
驼峰式命名法
¥Camel Case
Kebab Case
因此,例如,你可以监听 htmx:afterSwap
或 htmx:after-swap
。这有利于与其他库的互操作性。例如,Alpine.js 需要 kebab 大小写。
¥So, for example, you can listen for htmx:afterSwap
or for htmx:after-swap
. This facilitates interoperability
with other libraries. Alpine.js, for example, requires kebab case.
¥Logging
如果你在 htmx.logger
设置日志器,则每个事件都将被记录。这对于故障排除非常有用:
¥If you set a logger at htmx.logger
, every event will be logged. This can be very useful for troubleshooting:
htmx.logger = function(elt, event, data) {
if(console) {
console.log(event, elt, data);
}
}
¥Debugging
使用 htmx(或任何其他声明性语言)进行声明性和事件驱动编程可能是一项精彩且高效的活动,但与命令式方法相比,一个缺点是调试起来可能更棘手。
¥Declarative and event driven programming with htmx (or any other declarative language) can be a wonderful and highly productive activity, but one disadvantage when compared with imperative approaches is that it can be trickier to debug.
例如,如果你不知道技巧,弄清楚为什么某些事情没有发生可能会很困难。
¥Figuring out why something isn’t happening, for example, can be difficult if you don’t know the tricks.
好吧,这里有一些技巧:
¥Well, here are the tricks:
你可以使用的第一个调试工具是 htmx.logAll()
方法。这将记录 htmx 触发的每个事件,并允许你准确地看到库正在做什么。
¥The first debugging tool you can use is the htmx.logAll()
method. This will log every event that htmx triggers and
will allow you to see exactly what the library is doing.
htmx.logAll();
当然,这不会告诉你为什么 htmx 没有做某事。你可能还不知道 DOM 元素触发了哪些事件以用作触发器。为了解决这个问题,你可以使用浏览器控制台中提供的 monitorEvents()
方法:
¥Of course, that won’t tell you why htmx isn’t doing something. You might also not know what events a DOM
element is firing to use as a trigger. To address this, you can use the
monitorEvents()
method available in the
browser console:
monitorEvents(htmx.find("#theElement"));
这将把发生在 id 为 theElement
的元素上的所有事件吐出到控制台,并允许你准确地看到它发生了什么。
¥This will spit out all events that are occurring on the element with the id theElement
to the console, and allow you
to see exactly what is going on with it.
请注意,这只能从控制台工作,你不能将其嵌入到页面上的脚本标记中。
¥Note that this only works from the console, you cannot embed it in a script tag on your page.
最后,无论如何,你可能只想通过加载未最小化的版本来调试 htmx.js
。它大约有 2500 行 javascript,因此代码量并不大。你很可能希望在 issueAjaxRequest()
和 handleAjaxResponse()
方法中设置一个断点来查看发生了什么。
¥Finally, push come shove, you might want to just debug htmx.js
by loading up the unminimized version. It’s
about 2500 lines of javascript, so not an insurmountable amount of code. You would most likely want to set a break
point in the issueAjaxRequest()
and handleAjaxResponse()
methods to see what’s going on.
如果你需要帮助,请随时使用 Discord。
¥And always feel free to jump on the Discord if you need help.
¥Creating Demos
有时,为了演示错误或澄清用法,最好能够使用像 jsfiddle 这样的 javascript 代码段站点。为了方便创建演示,htmx 托管了一个演示脚本站点,该站点将安装:
¥Sometimes, in order to demonstrate a bug or clarify a usage, it is nice to be able to use a javascript snippet site like jsfiddle. To facilitate easy demo creation, htmx hosts a demo script site that will install:
htmx
hyperscript
请求模拟库
¥a request mocking library
只需将以下脚本标记添加到你的演示/小提琴/其他内容中:
¥Simply add the following script tag to your demo/fiddle/whatever:
<script src="https://demo.htmx.org"></script>
此辅助程序允许你通过添加带有 url
属性的 template
标签来添加模拟响应以指示哪个 URL。该 url 的响应将是模板的内部 HTML,从而可以轻松构建模拟响应。你可以使用 delay
属性为响应添加延迟,该属性应为一个整数,表示要延迟的毫秒数
¥This helper allows you to add mock responses by adding template
tags with a url
attribute to indicate which URL.
The response for that url will be the innerHTML of the template, making it easy to construct mock responses. You can
add a delay to the response with a delay
attribute, which should be an integer indicating the number of milliseconds
to delay
你可以使用 ${}
语法在模板中嵌入简单的表达式。
¥You may embed simple expressions in the template with the ${}
syntax.
请注意,这只应用于演示,并且不能保证长时间工作,因为它将始终抓取最新版本的 htmx 和 hyperscript!
¥Note that this should only be used for demos and is in no way guaranteed to work for long periods of time as it will always be grabbing the latest versions htmx and hyperscript!
¥Demo Example
以下是代码示例:
¥Here is an example of the code in action:
<!-- load demo environment -->
<script src="https://demo.htmx.org"></script>
<!-- post to /foo -->
<button hx-post="/foo" hx-target="#result">
Count Up
</button>
<output id="result"></output>
<!-- respond to /foo with some dynamic content in a template tag -->
<script>
globalInt = 0;
</script>
<template url="/foo" delay="500"> <!-- note the url and delay attributes -->
${globalInt++}
</template>
¥Scripting
虽然 htmx 鼓励使用超媒体方法来构建 Web 应用,但它也为客户端脚本提供了许多选项。脚本包含在 REST-ful Web 架构描述中,请参阅:按需代码。在可行的情况下,我们建议在你的 Web 应用中使用 hypermedia-friendly 方法编写脚本:
¥While htmx encourages a hypermedia approach to building web applications, it offers many options for client scripting. Scripting is included in the REST-ful description of web architecture, see: Code-On-Demand. As much as is feasible, we recommend a hypermedia-friendly approach to scripting in your web application:
htmx 和脚本解决方案之间的主要集成点是 htmx 发送并可响应的 events。有关通过事件将 JavaScript 库与 htmx 集成的良好模板,请参阅 第三方 Javascript 部分中的 SortableJS 示例。
¥The primary integration point between htmx and scripting solutions is the events that htmx sends and can respond to. See the SortableJS example in the 3rd Party Javascript section for a good template for integrating a JavaScript library with htmx via events.
与 htmx 完美匹配的脚本解决方案包括:
¥Scripting solutions that pair well with htmx include:
VanillaJS - 只需使用 JavaScript 的内置功能挂接事件处理程序以响应 htmx 发出的事件,就可以很好地编写脚本。这是一种非常轻量级且越来越流行的方法。
¥VanillaJS - Simply using the built-in abilities of JavaScript to hook in event handlers to respond to the events htmx emits can work very well for scripting. This is an extremely lightweight and increasingly popular approach.
AlpineJS - Alpine.js 提供了一套丰富的工具来创建复杂的前端脚本,包括反应式编程支持,同时仍然保持极轻量级。Alpine 鼓励使用我们认为与 htmx 完美匹配的 “内联脚本” 方法。
¥AlpineJS - Alpine.js provides a rich set of tools for creating sophisticated front end scripts, including reactive programming support, while still remaining extremely lightweight. Alpine encourages the “inline scripting” approach that we feel pairs well with htmx.
jQuery - 尽管它在某些圈子里已经存在很久了,而且名声很好, jQuery 与 htmx 搭配得很好,特别是在已经包含大量 jQuery 的旧代码库中。
¥jQuery - Despite its age and reputation in some circles, jQuery pairs very well with htmx, particularly in older code-bases that already have a lot of jQuery in them.
hyperscript - Hyperscript 是一种实验性的前端脚本语言,由创建 htmx 的同一团队创建。它被设计为很好地嵌入 HTML,既能响应事件,又能创建事件,并且与 htmx 很好地配对。
¥hyperscript - Hyperscript is an experimental front-end scripting language created by the same team that created htmx. It is designed to embed well in HTML and both respond to and create events, and pairs very well with htmx.
我们有一整章题为 我们的书 中的 “客户端脚本”,介绍如何将脚本集成到基于 htmx 的应用中。
¥We have an entire chapter entitled “Client-Side Scripting” in our book that looks at how scripting can be integrated into your htmx-based application.
hx-on*
属性HTML 允许通过 onevent
属性 嵌入内联脚本,例如 onClick
:
¥HTML allows the embedding of inline scripts via the onevent
properties,
such as onClick
:
<button onclick="alert('You clicked me!')">
Click Me!
</button>
此功能允许脚本逻辑与逻辑适用的 HTML 元素共存,从而提供良好的 行为局部性 (LoB)。不幸的是,HTML 仅允许固定数量的 特定 DOM 事件(例如 onclick
)具有 on*
属性,并且不提供响应元素上任意事件的通用机制。
¥This feature allows scripting logic to be co-located with the HTML elements the logic applies to, giving good
Locality of Behaviour (LoB). Unfortunately, HTML only allows on*
attributes for a fixed
number of specific DOM events (e.g. onclick
) and
doesn’t provide a generalized mechanism for responding to arbitrary events on elements.
为了解决这一缺点,htmx 提供了 hx-on*
属性。这些属性允许你以保留标准 on*
属性的 LoB 的方式响应任何事件。
¥In order to address this shortcoming, htmx offers hx-on*
attributes. These attributes allow
you to respond to any event in a manner that preserves the LoB of the standard on*
properties.
如果我们想使用 hx-on
属性来响应 click
事件,我们会这样写:
¥If we wanted to respond to the click
event using an hx-on
attribute, we would write this:
<button hx-on:click="alert('You clicked me!')">
Click Me!
</button>
因此,字符串 hx-on
,后跟冒号(或破折号),然后是事件的名称。
¥So, the string hx-on
, followed by a colon (or a dash), then by the name of the event.
对于 click
事件,当然,我们建议坚持使用标准 onclick
属性。但是,考虑一个 htmx 驱动的按钮,它希望使用 htmx:config-request
事件向请求添加参数。使用标准 on*
属性无法实现这一点,但可以使用 hx-on:htmx:config-request
属性来实现:
¥For a click
event, of course, we would recommend sticking with the standard onclick
attribute. However, consider an
htmx-powered button that wishes to add a parameter to a request using the htmx:config-request
event. This would not
be possible using a standard on*
property, but it can be done using the hx-on:htmx:config-request
attribute:
<button hx-post="/example"
hx-on:htmx:config-request="event.detail.parameters.example = 'Hello Scripting!'">
Post Me!
</button>
在此,example
参数在发出 POST
请求之前添加到其中值 ‘你好,脚本!’。
¥Here the example
parameter is added to the POST
request before it is issued, with the value ‘Hello Scripting!’.
另一个用例是使用 afterRequest
事件对成功请求进行 重置用户输入,从而避免需要像带外交换这样的操作。
¥Another usecase is to reset user input on successful requests using the afterRequest
event, avoiding the need for something like an out of band swap.
hx-on*
属性是一种非常简单的通用嵌入式脚原生制。它不能替代更全面开发的前端脚本解决方案(如 AlpineJS 或 hyperscript)。但是,它可以增强基于 VanillaJS 的脚本方法,以在你的 htmx 驱动的应用中运行。
¥The hx-on*
attributes are a very simple mechanism for generalized embedded scripting. It is not a replacement for more
fully developed front-end scripting solutions such as AlpineJS or hyperscript. It can, however, augment a VanillaJS-based
approach to scripting in your htmx-powered application.
请注意,HTML 属性不区分大小写。这意味着,不幸的是,依赖大写字母/驼峰式大小写的事件无法得到响应。如果你需要支持驼峰式事件,我们建议使用功能更齐全的脚本解决方案,例如 AlpineJS 或 hyperscript。正是出于这个原因,htmx 以 camelCase 和 kebab-case 调度其所有事件。
¥Note that HTML attributes are case insensitive. This means that, unfortunately, events that rely on capitalization/ camel casing, cannot be responded to. If you need to support camel case events we recommend using a more fully functional scripting solution such as AlpineJS or hyperscript. htmx dispatches all its events in both camelCase and in kebab-case for this very reason.
¥3rd Party Javascript
Htmx 与第三方库集成得相当好。如果库在 DOM 上触发事件,你可以使用这些事件触发来自 htmx 的请求。
¥Htmx integrates fairly well with third party libraries. If the library fires events on the DOM, you can use those events to trigger requests from htmx.
一个很好的例子是 SortableJS 演示:
¥A good example of this is the SortableJS demo:
<form class="sortable" hx-post="/items" hx-trigger="end">
<div class="htmx-indicator">Updating...</div>
<div><input type='hidden' name='item' value='1'/>Item 1</div>
<div><input type='hidden' name='item' value='2'/>Item 2</div>
<div><input type='hidden' name='item' value='2'/>Item 3</div>
</form>
与大多数 javascript 库一样,使用 Sortable 时,你需要在某个时候初始化内容。
¥With Sortable, as with most javascript libraries, you need to initialize content at some point.
在 jquery 中,你可以这样做:
¥In jquery you might do this like so:
$(document).ready(function() {
var sortables = document.body.querySelectorAll(".sortable");
for (var i = 0; i < sortables.length; i++) {
var sortable = sortables[i];
new Sortable(sortable, {
animation: 150,
ghostClass: 'blue-background-class'
});
}
});
在 htmx 中,你应改用 htmx.onLoad
函数,并且只从新加载的内容中进行选择,而不是从整个文档中进行选择:
¥In htmx, you would instead use the htmx.onLoad
function, and you would select only from the newly loaded content,
rather than the entire document:
htmx.onLoad(function(content) {
var sortables = content.querySelectorAll(".sortable");
for (var i = 0; i < sortables.length; i++) {
var sortable = sortables[i];
new Sortable(sortable, {
animation: 150,
ghostClass: 'blue-background-class'
});
}
})
这将确保当 htmx 将新内容添加到 DOM 时,可排序元素得到正确初始化。
¥This will ensure that as new content is added to the DOM by htmx, sortable elements are properly initialized.
如果 javascript 将内容添加到具有 htmx 属性的 DOM,则需要确保使用 htmx.process()
函数初始化此内容。
¥If javascript adds content to the DOM that has htmx attributes on it, you need to make sure that this content
is initialized with the htmx.process()
function.
例如,如果你要使用 fetch
API 获取一些数据并将其放入 div 中,并且该 HTML 中包含 htmx 属性,则需要添加对 htmx.process()
的调用,如下所示:
¥For example, if you were to fetch some data and put it into a div using the fetch
API, and that HTML had
htmx attributes in it, you would need to add a call to htmx.process()
like this:
let myDiv = document.getElementById('my-div')
fetch('http://example.com/movies.json')
.then(response => response.text())
.then(data => { myDiv.innerHTML = data; htmx.process(myDiv); } );
一些第三方库从 HTML 模板元素创建内容。例如,Alpine JS 使用模板上的 x-if
属性有条件地添加内容。此类模板最初不是 DOM 的一部分,如果它们包含 htmx 属性,则在加载后需要调用 htmx.process()
。以下示例使用 Alpine 的 $watch
函数来查找将触发条件内容的值的变化:
¥Some 3rd party libraries create content from HTML template elements. For instance, Alpine JS uses the x-if
attribute on templates to add content conditionally. Such templates are not initially part of the DOM and,
if they contain htmx attributes, will need a call to htmx.process()
after they are loaded. The following
example uses Alpine’s $watch
function to look for a change of value that would trigger conditional content:
<div x-data="{show_new: false}"
x-init="$watch('show_new', value => {
if (show_new) {
htmx.process(document.querySelector('#new_content'))
}
})">
<button @click = "show_new = !show_new">Toggle New Content</button>
<template x-if="show_new">
<div id="new_content">
<a hx-get="/server/newstuff" href="#">New Clickable</a>
</div>
</template>
</div>
¥Web Components
有关如何将 htmx 与 Web 组件集成的示例,请参阅 Web 组件示例 页面。
¥Please see the Web Components Examples page for examples on how to integrate htmx with web components.
¥Caching
htmx 开箱即用,可与标准 HTTP 缓存 机制配合使用。
¥htmx works with standard HTTP caching mechanisms out of the box.
如果你的服务器将 Last-Modified
HTTP 响应标头添加到给定 URL 的响应中,则浏览器会自动将 If-Modified-Since
请求 HTTP 标头添加到对同一 URL 的下一个请求中。请注意,如果你的服务器可以根据其他一些标头为同一个 URL 渲染不同的内容,则你需要使用 Vary
响应 HTTP 标头。例如,如果你的服务器在缺少 HX-Request
标头或 false
时渲染完整的 HTML,而在 HX-Request: true
时渲染该 HTML 的片段,则需要添加 Vary: HX-Request
。这会导致缓存基于响应 URL 和 HX-Request
请求标头的组合进行键入 - 而不是仅基于响应 URL。
¥If your server adds the
Last-Modified
HTTP response header to the response for a given URL, the browser will automatically add the
If-Modified-Since
request HTTP header to the next requests to the same URL. Be mindful that if
your server can render different content for the same URL depending on some other
headers, you need to use the Vary
response HTTP header. For example, if your server renders the full HTML when the
HX-Request
header is missing or false
, and it renders a fragment of that HTML
when HX-Request: true
, you need to add Vary: HX-Request
. That causes the cache to be
keyed based on a composite of the response URL and the HX-Request
request header —
rather than being based just on the response URL.
如果你无法(或不愿意)使用 Vary
标头,则可以将配置参数 getCacheBusterParam
设置为 true
。如果设置了此配置变量,htmx 将在其发出的 GET
请求中包含一个缓存破坏参数,这将阻止浏览器在同一个缓存槽中缓存基于 htmx 和非基于 htmx 的响应。
¥If you are unable (or unwilling) to use the Vary
header, you can alternatively set the configuration parameter
getCacheBusterParam
to true
. If this configuration variable is set, htmx will include a cache-busting parameter
in GET
requests that it makes, which will prevent browsers from caching htmx-based and non-htmx based responses
in the same cache slot.
htmx 也可以按预期与 ETag
配合使用。请注意,如果你的服务器可以为同一个 URL 渲染不同的内容(例如,取决于 HX-Request
标头的值),则服务器需要为每个内容生成不同的 ETag
。
¥htmx also works with ETag
as expected. Be mindful that if your server can render different content for the same
URL (for example, depending on the value of the HX-Request
header), the server needs
to generate a different ETag
for each content.
¥Security
htmx 允许你直接在 DOM 中定义逻辑。这有许多优点,最大的优点是 位置行为,它使你的系统更易于理解和维护。
¥htmx allows you to define logic directly in your DOM. This has a number of advantages, the largest being Locality of Behavior, which makes your system easier to understand and maintain.
但是,这种方法的一个问题是安全性:由于 htmx 增加了 HTML 的表现力,如果恶意用户能够将 HTML 注入你的应用,他们就可以利用 htmx 的这种表现力来达到恶意目的。
¥A concern with this approach, however, is security: since htmx increases the expressiveness of HTML, if a malicious user is able to inject HTML into your application, they can leverage this expressiveness of htmx to malicious ends.
¥Rule 1: Escape All User Content
基于 HTML 的 Web 开发的第一条规则一直是:不信任用户的输入。你应该转义注入到你网站的所有第三方不受信任的内容。这是为了防止 XSS 攻击 等问题。
¥The first rule of HTML-based web development has always been: do not trust input from the user. You should escape all 3rd party, untrusted content that is injected into your site. This is to prevent, among other issues, XSS attacks.
在优秀的 OWASP 网站(包括 跨站点脚本预防备忘单)上,有大量关于 XSS 及其预防方法的文档。
¥There is extensive documentation on XSS and how to prevent it on the excellent OWASP Website, including a Cross Site Scripting Prevention Cheat Sheet.
好消息是,这是一个非常古老且易于理解的主题,绝大多数服务器端模板语言都支持内容的 自动转义,以防止出现此类问题。
¥The good news is that this is a very old and well understood topic, and the vast majority of server-side templating languages support automatic escaping of content to prevent just such an issue.
话虽如此,有时人们会选择更危险地注入 HTML,通常是通过模板语言中的某种 raw()
机制。这样做是有充分理由的,但如果注入的内容来自第三方,则必须清理它,包括删除以 hx-
和 data-hx
开头的属性,以及内联 <script>
标签等。
¥That being said, there are times people choose to inject HTML more dangerously, often via some sort of raw()
mechanism in their templating language. This can be done for good reasons, but if the content being injected is coming
from a 3rd party then it must be scrubbed, including removing attributes starting with hx-
and data-hx
, as well as
inline <script>
tags, etc.
如果你正在注入原始 HTML 并进行自己的转义,最佳做法是将你允许的属性和标签列入白名单,而不是将你不允许的属性和标签列入黑名单。
¥If you are injecting raw HTML and doing your own escaping, a best practice is to whitelist the attributes and tags you allow, rather than to blacklist the ones you disallow.
¥htmx Security Tools
当然,错误总是会发生,开发者也不是完美的,因此最好为你的 Web 应用采用分层的安全方法,并且 htmx 也提供了帮助保护你的应用的工具。
¥Of course, bugs happen and developers are not perfect, so it is good to have a layered approach to security for your web application, and htmx provides tools to help secure your application as well.
让我们来看看它们。
¥Let’s take a look at them.
hx-disable
htmx 提供的第一个帮助进一步保护你的应用的工具是 hx-disable
属性。此属性将阻止处理给定元素上的所有 htmx 属性以及其中的所有元素。因此,例如,如果你在模板中包含原始 HTML 内容(再次强调,不建议这样做!),则可以在内容周围放置一个带有 hx-disable
属性的 div:
¥The first tool htmx provides to help further secure your application is the hx-disable
attribute. This attribute will prevent processing of all htmx attributes on a given element, and on all elements within
it. So, for example, if you were including raw HTML content in a template (again, this is not recommended!) then you
could place a div around the content with the hx-disable
attribute on it:
<div hx-disable>
<%= raw(user_content) %>
</div>
并且 htmx 不会处理在该内容中找到的任何与 htmx 相关的属性或功能。此属性无法通过注入更多内容来禁用:如果在元素的父层次结构中的任何位置发现 hx-disable
属性,则 htmx 将不会处理它。
¥And htmx will not process any htmx-related attributes or features found in that content. This attribute cannot be
disabled by injecting further content: if an hx-disable
attribute is found anywhere in the parent hierarchy of an
element, it will not be processed by htmx.
hx-history
另一个安全考虑因素是 htmx 历史记录缓存。你可能有一些页面包含敏感数据,你不想将其存储在用户的 localStorage
缓存中。你可以通过在页面的任何位置包含 hx-history
属性并将其值设置为 false
,从历史缓存中省略给定页面。
¥Another security consideration is htmx history cache. You may have pages that have sensitive data that you do not
want stored in the users localStorage
cache. You can omit a given page from the history cache by including the
hx-history
attribute anywhere on the page, and setting its value to false
.
¥Configuration Options
htmx 还提供与安全相关的配置选项:
¥htmx also provides configuration options related to security:
htmx.config.selfRequestsOnly
- 如果设置为 true
,则只允许向与当前文档相同的域发出请求
¥htmx.config.selfRequestsOnly
- if set to true
, only requests to the same domain as the current document will be allowed
htmx.config.allowScriptTags
- htmx 将处理在其加载的新内容中找到的 <script>
标签。如果你希望禁用此行为,可以将此配置变量设置为 false
¥htmx.config.allowScriptTags
- htmx will process <script>
tags found in new content it loads. If you wish to disable
this behavior you can set this configuration variable to false
htmx.config.historyCacheSize
- 可以设置为 0
以避免在 localStorage
缓存中存储任何 HTML
¥htmx.config.historyCacheSize
- can be set to 0
to avoid storing any HTML in the localStorage
cache
htmx.config.allowEval
- 可以设置为 false
以禁用所有依赖 eval 的 htmx 功能:
¥htmx.config.allowEval
- can be set to false
to disable all features of htmx that rely on eval:
事件过滤器
¥event filters
hx-on:
属性
¥hx-on:
attributes
带有 js:
前缀的 hx-vals
¥hx-vals
with the js:
prefix
带有 js:
前缀的 hx-headers
¥hx-headers
with the js:
prefix
请注意,通过禁用 eval()
删除的所有功能都可以使用你自己的自定义 javascript 和 htmx 事件模型重新实现。
¥Note that all features removed by disabling eval()
can be reimplemented using your own custom javascript and the
htmx event model.
¥Events
如果你希望允许对当前主机之外的某些域的请求,但不完全开放,则可以使用 htmx:validateUrl
事件。此事件将在 detail.url
插槽中提供请求 URL,以及 sameHost
属性。
¥If you want to allow requests to some domains beyond the current host, but not leave things totally open, you can
use the htmx:validateUrl
event. This event will have the request URL available in the detail.url
slot, as well
as a sameHost
property.
你可以检查这些值,如果请求无效,则在事件上调用 preventDefault()
以防止发出请求。
¥You can inspect these values and, if the request is not valid, invoke preventDefault()
on the event to prevent the
request from being issued.
document.body.addEventListener('htmx:validateUrl', function (evt) {
// only allow requests to the current server as well as myserver.com
if (!evt.detail.sameHost && evt.detail.url.hostname !== "myserver.com") {
evt.preventDefault();
}
});
¥CSP Options
浏览器还提供进一步保护你的 Web 应用的工具。最强大的工具是 内容安全策略。使用 CSP,你可以告诉浏览器,例如,不要向非原始主机发出请求,不要评估内联脚本标记等。
¥Browsers also provide tools for further securing your web application. The most powerful tool available is a Content Security Policy. Using a CSP you can tell the browser to, for example, not issue requests to non-origin hosts, to not evaluate inline script tags, etc.
以下是 meta
标签中的 CSP 示例:
¥Here is an example CSP in a meta
tag:
<meta http-equiv="Content-Security-Policy" content="default-src 'self';">
这告诉浏览器 “仅允许连接到原始(源)域”。这对于 htmx.config.selfRequestsOnly
来说是多余的,但在处理应用安全性时,分层安全性方法是必要的,而且实际上也是理想的。
¥This tells the browser “Only allow connections to the original (source) domain”. This would be redundant with the
htmx.config.selfRequestsOnly
, but a layered approach to security is warranted and, in fact, ideal, when dealing
with application security.
对 CSP 的完整讨论超出了本文档的范围,但 MDN 文章 为探索该主题提供了一个很好的起点。
¥A full discussion of CSPs is beyond the scope of this document, but the MDN Article provide a good jumping off point for exploring this topic.
¥CSRF Prevention
CSRF 令牌的分配和检查通常是后端职责,但 htmx
可以支持使用 hx-headers
属性在每次请求时自动返回 CSRF 令牌。该属性需要添加到发出请求的元素或其祖级元素之一。这使得 html
和 body
元素成为将 CSRF 令牌添加到 HTTP
请求标头的有效全局载体,如下所示。
¥The assignment and checking of CSRF tokens are typically backend responsibilities, but htmx
can support returning the CSRF token automatically with every request using the hx-headers
attribute. The attribute needs to be added to the element issuing the request or one of its ancestor elements. This makes the html
and body
elements effective global vehicles for adding the CSRF token to the HTTP
request header, as illustrated below.
<html lang="en" hx-headers='{"X-CSRF-TOKEN": "CSRF_TOKEN_INSERTED_HERE"}'>
:
</html>
<body hx-headers='{"X-CSRF-TOKEN": "CSRF_TOKEN_INSERTED_HERE"}'>
:
</body>
上述元素在 HTML 文档中通常是唯一的,并且应该很容易在模板中找到。
¥The above elements are usually unique in an HTML document and should be easy to locate within templates.
¥Configuring htmx
Htmx 有一些配置选项,可以通过编程或声明方式访问。它们列在下面:
¥Htmx has some configuration options that can be accessed either programmatically or declaratively. They are listed below:
配置变量 | 信息 |
---|---|
htmx.config.historyEnabled | 默认为 true ,真的只对测试有用 |
htmx.config.historyCacheSize | 默认为 10 |
htmx.config.refreshOnHistoryMiss | 默认为 false ,如果设置为 true ,htmx 将在历史记录未命中时发出整页刷新,而不是使用 AJAX 请求 |
htmx.config.defaultSwapStyle | 默认为 innerHTML |
htmx.config.defaultSwapDelay | 默认为 0 |
htmx.config.defaultSettleDelay | 默认为 20 |
htmx.config.includeIndicatorStyles | 默认为 true (确定指示器样式是否已加载) |
htmx.config.indicatorClass | 默认为 htmx-indicator |
htmx.config.requestClass | 默认为 htmx-request |
htmx.config.addedClass | 默认为 htmx-added |
htmx.config.settlingClass | 默认为 htmx-settling |
htmx.config.swappingClass | 默认为 htmx-swapping |
htmx.config.allowEval | 默认为 true ,可用于禁用 htmx 对某些功能的 eval 使用(例如触发过滤器) |
htmx.config.allowScriptTags | 默认为 true ,确定 htmx 是否会处理在新内容中找到的脚本标记 |
htmx.config.inlineScriptNonce | 默认为 '' ,意味着不会向内联脚本添加任何 nonce |
htmx.config.attributesToSettle | 默认为 ["class", "style", "width", "height"] ,在稳定阶段要稳定的属性 |
htmx.config.inlineStyleNonce | 默认为 '' ,意味着不会向内联样式添加任何 nonce |
htmx.config.useTemplateFragments | 默认为 false ,用于解析来自服务器的内容的 HTML 模板标记(与 IE11 不兼容!) |
htmx.config.wsReconnectDelay | 默认为 full-jitter |
htmx.config.wsBinaryType | 默认为 blob ,通过 WebSocket 连接接收 二进制数据的类型 |
htmx.config.disableSelector | 默认为 [hx-disable], [data-hx-disable] ,htmx 将不会处理带有此属性或其父级的元素 |
htmx.config.withCredentials | 默认为 false ,允许使用凭据(例如 cookie、授权标头或 TLS 客户端证书)进行跨站点访问控制请求 |
htmx.config.timeout | 默认为 0,请求在自动终止前可能需要的毫秒数 |
htmx.config.scrollBehavior | 默认为 ‘instant’,将 show 修饰符与 hx-swap 一起使用时的滚动行为。允许的值为 instant (滚动应在一次跳转中立即发生)、smooth (滚动应流畅地进行动画处理)和 auto (滚动行为由 scroll-behavior 的计算值决定)。 |
htmx.config.defaultFocusScroll | 如果焦点元素应该滚动到视图中,则默认为 false,可以使用 focus-scroll swap 修饰符进行覆盖。 |
htmx.config.getCacheBusterParam | 默认为 false,如果设置为 true,htmx 将以 org.htmx.cache-buster=targetElementId 格式将目标元素附加到 GET 请求 |
htmx.config.globalViewTransitions | 如果设置为 true ,htmx 将在交换新内容时使用 查看转换 API。 |
htmx.config.methodsThatUseUrlParams | 默认为 ["get", "delete"] ,htmx 将通过在 URL 中编码其参数(而不是请求正文)来格式化使用这些方法的请求 |
htmx.config.selfRequestsOnly | 默认为 true ,是否仅允许对与当前文档相同的域进行 AJAX 请求 |
htmx.config.ignoreTitle | 默认为 false ,如果设置为 true ,当在新内容中找到 title 标记时,htmx 将不会更新文档的标题 |
htmx.config.disableInheritance | 禁用 htmx 中的属性继承,然后可以通过 hx-inherit 属性覆盖 |
htmx.config.scrollIntoViewOnBoost | 默认为 true ,增强元素的目标是否滚动到视口中。如果在提升元素上省略 hx-target ,则目标默认为 body ,导致页面滚动到顶部。 |
htmx.config.triggerSpecsCache | 默认为 null ,将评估的触发器规范存储到其中的缓存,以更多的内存使用为代价提高解析性能。你可以定义一个简单的对象来使用永不清除的缓存,或者使用 代理对象 实现你自己的系统 |
htmx.config.responseHandling | 响应状态代码的默认 响应处理 行为可以在此处配置为交换或错误 |
htmx.config.allowNestedOobSwaps | 默认为 true ,是否处理嵌套在主响应元素中的元素的 OOB 交换。参见 嵌套 OOB 交换。 |
你可以直接在 javascript 中设置它们,也可以使用 meta
标签:
¥You can set them directly in javascript, or you can use a meta
tag:
<meta name="htmx-config" content='{"defaultSwapStyle":"outerHTML"}'>
¥Conclusion
就是这样!
¥And that’s it!
祝你使用 htmx 愉快!你无需编写大量代码即可完成 相当多!
¥Have fun with htmx! You can accomplish quite a bit without writing a lot of code!