Skip to content

htmx - 适用于 HTML 的高功率工具

警告:本文由机器翻译生成,可能导致质量不佳或信息有误,请谨慎阅读!

简而言之的htmx

HTMX是一个库,可让您直接从HTML访问现代浏览器功能,而不是使用 JavaScript。

要了解HTMX,首先让我们看一个锚标记:

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

此锚标记告诉一个浏览器:

“When a user clicks on this link, issue an HTTP GET request to ‘/blog’ and load the response content into the browser window” 。

考虑到这一点,请考虑以下html的点:

<button hx-post= "/clicked"
hx-trigger= "click"
hx-target= "#parent-div"
hx-swap= "outerHTML"
>
Click Me!
</button>

这告诉HTMX:

“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的核心思想为超文本,直接打开更多可能性 在语言中:

*现在,任何元素,不仅是锚和表格都可以发出HTTP请求 *现在任何事件,不仅是单击或表单提交,都可以触发请求 *现在 http动词 , 不只是 GETPOST 可以使用 *现在,任何元素,不仅是整个窗口,都可以是通过请求进行更新的目标

请注意,当您使用HTMX时,在服务器端,通常会以 *HTML *响应,而不是 *JSON *。 这使您坚定地 在 原始网络编程模型 ,,,, 使用 超文本作为应用状态的引擎 甚至无需真正理解这个概念。

值得一提的是,如果您愿意,可以使用 data- 使用HTMX时的前缀:

<a data-hx-post= "/click" >Click Me!</a>

安装

HTMX是一种依赖性- 免费,浏览器- 定向的JavaScript库。 这意味着使用它就像添加一个 <script> 标记您的文档头。 无需复杂的构建步骤或系统。

如果您从InterCooler.js迁移到HTMX,请参阅 迁移指南

通过CDN(例如Unpkg.com)

与HTMX一起使用的最快方法是通过CDN加载它。 您可以简单地将其添加到您的头标签中 然后开始:

<script src= "https://unpkg.com/[email protected]" integrity= "sha384-ujb1lZYygJmzgSwoxRggbCHcjc0rB2XoQrxeTUQyRjrOnlCoYta87iKBWq3EsdM2" crossorigin= "anonymous" ></script>

也可以使用未启示的版本

<script src= "https://unpkg.com/[email protected]/dist/htmx.js" integrity= "sha384-qbtR4rS9RrUMECUWDWM2+YGgN3U4V4ZncZ0BvUcg9FGct0jqXz3PUdVpU1p0yrXS" crossorigin= "anonymous" ></script>

虽然CDN方法非常简单,但您可能需要考虑 在生产中不使用CDN

下载副本

安装HTMX的下一个最简单方法是简单地将其复制到您的项目中。

下载 htmx.min.js 来自unpkg.com 并将其添加到项目中的适当目录中 并在必要的情况下与 <script> 标签:

<script src= "/path/to/htmx.min.js" ></script>

您也可以通过从中下载它们来以这种方式添加扩展 ext/ 目录。

NPM

对于NPM- 样式构建系统,您可以通过 NPM

Terminal window
npm install htmx.org

安装后,您需要使用适当的工具来使用 node_modules/htmx.org/dist/htmx.js (或者 .min.js )。 例如,您可能会将HTMX与一些扩展和项目捆绑在一起- 特定代码。

webpack

如果您使用的是WebPack来管理JavaScript:

  • 安装 htmx 通过您喜欢的软件包管理器(例如NPM或纱线) *将导入添加到您的 index.js
import 'htmx.org';

如果您想使用全局 htmx 变量(建议),您需要将其注入窗口范围:

*创建自定义JS文件 *将此文件导入您的 index.js (从步骤2进口的下方)

import 'path/to/my_custom.js';

*然后将此代码添加到文件:

window.htmx = require('htmx.org');

*最后,重建您的捆绑包

AJAX

HTMX的核心是一组属性,可让您直接从HTML发出AJAX请求:

属性描述
HX- 得到发行 GET 请求给定的URL
HX- 邮政发行 POST 请求给定的URL
HX- 放发行 PUT 请求给定的URL
HX- 修补发行 PATCH 请求给定URL
HX- 删除发行 DELETE 请求给定URL

这些属性中的每一个都需要URL向Ajax请求发出。 该元素将发出指定的请求 当元素为时,输入给定的URL 触发

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

这告诉浏览器:

当用户点击此DIV时,向URL /消息发出put请求,然后将响应加载到DIV中

触发请求

默认情况下,AJAX请求是由 “natural” 元素的事件:

  • input ,,,, textareaselect 被触发在 change 事件
  • formsubmit 事件 *其他一切都是由 click 事件

如果您想要不同的行为,可以使用 HX- 扳机 属性以指定哪个事件将导致请求。

这里有一个 div 帖子到 /mouse_entered 当鼠标进入它时:

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

触发修饰符

触发器还可以还有一些其他改变其行为的修饰符。 例如,如果您只想请求 发生一次,您可以使用 once 触发器的修饰符:

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

您可以用于触发器的其他修饰符是:

  • changed - 仅当元素的值已更改时就发布请求
  • delay:<time interval> - 等待给定的时间(例如 1s ) 前 发出请求。 如果事件再次触发,倒计时将重置。
  • throttle:<time interval> - 等待给定的时间(例如 1s ) 前 发出请求。 与众不同 delay 如果在达到时间限制之前发生新事件,则将丢弃活动, 因此,请求将在时间段内触发。
  • from:<CSS Selector> - 在其他元素上聆听事件。 这可以用于键盘快捷键。

您可以使用这些属性来实现许多常见的UX模式,例如 主动搜索

<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>

如果输入已更改并插入结果,则此输入将在关键UP事件之后发布500毫秒 进入 div 使用ID search-results

可以在 HX- 扳机 属性,被逗号隔开。

触发过滤器

您也可以通过在事件名称之后使用方括号应用触发过滤器,并包含JavaScript表达式 将进行评估。 如果表达式评估为 true 该事件将触发,否则不会。

这是一个仅在控件上触发的示例- 点击元素

<div hx-get= "/clicked" hx-trigger= "click[ctrlKey]" >
Control Click Me
</div>

类似的属性 ctrlKey 将首先针对触发事件,然后是全球范围解决。 这 this 符号将设置为当前元素。

特别活动

HTMX提供了一些特殊事件,可用于 HX- 扳机

  • load - 首次加载元素时发射一次
  • revealed - 当元素首次滚动到视口时发射一次
  • intersect - 当元素首次与视口相交时,一次发射一次。 这支持了两个其他选项:
  • root:<selector> - 相交根元素的CSS选择器
  • threshold:<float> - 浮点数在0.0到1.0之间

如果您有高级用例,也可以使用自定义事件触发请求。

轮询

如果您希望元素对给定的URL进行轮询而不是等待事件,则可以使用 every 句法 与 hx-trigger 属性:

<div hx-get= "/news" hx-trigger= "every 2s" ></div>

这告诉HTMX

每2秒钟,发出a to /news并将响应加载到div

如果要停止从服务器响应中进行轮询,则可以使用HTTP响应代码响应 [286](https://en.wikipedia.org/wiki/86_(term) ) 元素将取消投票。

负载投票

可以用来在HTMX中进行投票的另一种技术是 “load polling” ,元素指定的地方 A load 触发与延迟一起,并用响应代替:

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

如果是 /messages 终点一直以这种方式返回DIV,它将保持 “polling” 回到每个网址 第二。

在民意测验的情况下,民意测验的负载投票可能很有用 当您向用户展示一个 进度条

请求指标

发出AJAX请求时,通常会让用户知道以来发生的事情正在发生 不会给他们任何反馈。 您可以在HTMX中使用 htmx-indicator 班级。

htmx-indicator 定义了类,以便默认情况下,任何元素的不透明度为0,使其变得不可见 但存在于DOM中。

当HTMX发出请求时,它将提出 htmx-request 将上课到一个元素(请求元素或 另一个元素,如果指定)。 这 htmx-request 上课会导致子元素 htmx-indicator 班级 在其过渡到1个不透明度上,显示指标。

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

在这里,我们有一个按钮。 单击时 htmx-request 课程将添加到其中,这将显示旋转器 GIF元素。 (我喜欢 SVG旋转器 这些日子。)

htmx-indicator 课程使用不透明度隐藏和显示进度指标,如果您希望其他机制 您可以像这样创建自己的CSS过渡:

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

如果你想要 htmx-request 添加到其他元素中的类,您可以使用 HX- 指标 使用CSS选择器属性来实现:

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

在这里,我们通过ID明确指出指示器。 请注意,我们本可以将班级放在父母身上 div 也是如此 并产生相同的效果。

您也可以添加 disabled 属性 到 通过使用该请求期间的元素 HX- 禁用- 埃尔特 属性。

目标

如果您希望将响应加载到提出请求的元素以外的其他元素中,则可以 使用 HX- 目标 属性,该属性采用CSS选择器。 回顾我们的现场搜索示例:

<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 ,而不是进入 输入标签。

扩展的CSS选择器

hx-target ,以及使用CSS选择器的大多数属性,支持 “extended” CSS语法:

*您可以使用 this 关键字,这表明元素是 hx-target 属性是目标

  • closest <CSS selector> 语法会找到 最接近 祖先元素或自身,与给定的CSS选择器匹配。 (例如。 closest tr 将针对最接近元素的表行)
  • next <CSS selector> 语法将在DOM中找到匹配给定CSS选择器的下一个元素。
  • previous <CSS selector> 语法将在DOM中找到给定CSS选择器的先前元素。
  • find <CSS selector> 它将找到与给定CSS选择器相匹配的第一个儿童后代元素。 (例如 find tr 将第一个儿童后裔行定位到该元素)

此外,CSS选择器可能包裹在 </> 角色,模仿 查询字面意思 超级标题的语法。

像这样的相对目标对于创建灵活的用户界面而无需加载dom可以很有用 的 id 属性。

交换

HTMX提供了几种交换HTML返回到DOM的方法。 默认情况下,内容替换 innerHTML 目标元素。 您可以使用 HX- 交换 属性 具有以下任何值:

姓名描述
innerHTML默认值将内容放入目标元素中
outerHTML用返回的内容替换整个目标元素
afterbegin在目标内的第一个孩子之前预先介绍内容
beforebegin在目标父母元素中的目标之前预先启动内容
beforeend在目标内的最后一个孩子之后附加内容
afterend在目标父母元素中的目标之后附加内容
delete删除目标要素不管响应如何
none不会附加响应中的内容( 退出乐队 响应标题 仍将处理)

变形交换

除了上述标准交换机制外,HTMX还通过扩展支持_morphing_交换。 变形掉期 尝试将新内容_Merge_ _ merge_进入现有DOM,而不是简单地替换它。 他们经常做得更好 通过突变现有节点在- 在交换操作期间放置 CPU的成本。

以下扩展可用于变形- 样式掉期:

查看过渡

新的实验性 查看过渡API 为开发人员提供了一种在不同DOM状态之间创建动画过渡的方法。 它仍在积极发展 并且并非所有浏览器中都可以使用,但是HTMX提供了一种与此新API一起工作的方法- 过渡 机构如果在给定的浏览器中不可用API。

您可以使用以下方法对此新API进行实验:

*设置 htmx.config.globalViewTransitions 配置变量 true 将过渡用于所有掉期

  • 使用 transition:true 选项 hx-swap 属性 *如果元素交换由于上述任何一个配置而要过渡,则可以捕获 htmx:beforeTransition 事件并致电 preventDefault() 在其上取消过渡。

可以使用CSS配置查看过渡,如 该功能的镀铬文档

您可以在 动画示例 页。

交换选项

HX- 交换 属性支持许多调整HTMX交换行为的选项。 为了 例如,默认情况下,HTMX将在新内容中的任何位置上找到标题标签的标题交换。 你可以把这个 通过设置 ignoreTitle 修改器到true:

<button hx-post= "/like" hx-swap= "outerHTML ignoreTitle:true" >Like</button>

修饰符可在 hx-swap 是:

选项描述
transitiontrue 或者 false ,是否将视图过渡API用于此交换
swap使用的交换延迟(例如 100ms )何时清除旧内容并插入新内容
settle使用的定居延迟(例如 100ms )何时插入新内容以及何时解决
ignoreTitle如果设置为 true ,新内容中发现的任何标题都将被忽略,并且不会更新文档标题
scrolltop 或者 bottom ,将滚动目标元素到其顶部或底部
showtop 或者 bottom ,将滚动目标元素的顶部或底部滚动到视图

所有交换修饰符都会在指定交换样式后出现,并且是结肠- 分开。

看到 HX- 交换 文档以获取有关这些选项的更多详细信息。

同步

通常,您想协调两个元素之间的请求。 例如,您可能需要一个元素的请求 取代另一个元素的请求,或等到另一个元素的请求完成。

HTMX提供a hx-sync 属性可以帮助您完成此操作。

在此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

使用 hx-sync="closest form:abort" 在输入上,将注意表单上的请求,并在输入的请求中流产 出现表单请求或在输入请求在飞行中时开始:

<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>

这可以以声明的方式解决这两个元素之间的同步。

HTMX还支持一种取消请求的程序化方法:您可以发送 htmx:abort 事件到一个元素 取消任何内容- 航班请求:

<button id= "request-button" hx-post= "/example" >
Issue Request
</button>
<button onclick= "htmx.trigger('#request-button', 'htmx:abort')" >
Cancel Request
</button>

更多的示例和细节可以在 hx-sync 属性页。

CSS过渡

HTMX使使用易于使用 CSS过渡 没有 JavaScript。 考虑此HTML内容:

<div id= "div1" >Original Content</div>

想象一下,此内容由使用此新内容的AJAX请求替换为HTMX:

<div id= "div1" class= "red" >New Content</div>

注意两件事:

  • DIV在原始内容和新内容中具有 *相同的 * ID
  • red 课程已添加到新内容中

鉴于这种情况,我们可以编写从旧状态到新状态的CSS过渡:

.red {
color: red;
transition: all ease-in 1s ;
}

当此新内容中的HTMX交换时,它将以CSS过渡适用于新内容的方式进行操作。 为您提供了良好,平稳的过渡到新状态。

因此,总而言之,您要为元素使用CSS过渡所需要做的就是保持其 id 跨请求稳定!

你可以看到 动画示例 有关更多细节和现场演示。

细节

要了解CSS过渡在HTMX中的实际工作方式,您必须了解HTMX使用的基本交换和结算模型。

当从服务器收到新内容时,在交换内容之前,现有 对页面的内容进行了匹配的元素检查 id 属性。 如果是比赛 为新内容中的一个元素找到,复制旧内容的属性 在交换发生之前,请进入新元素。 然后将新内容交换了,但是 属性值。 最后,新属性值被交换了 “settle” 延迟 (默认情况下为20ms)。 有点疯狂,但这是允许CSS过渡在没有任何JavaScript的情况下工作的原因 开发人员。

从乐队交换

如果您想通过使用该响应直接将响应中的内容交换到DOM中 id 属性您可以使用 HX- 交换- OOB *响应 * html中的属性:

<div id= "message" hx-swap-oob= "true" >Swap me directly!</div>
Additional Content

在这个回应中, div#message 将直接交换到匹配的DOM元素中,而附加内容 将以正常方式换成目标。

您可以将此技术用于 “piggy-back” 其他请求更新。

选择要交换的内容

如果要选择响应HTML的子集以交换目标,则可以使用 HX- 选择 属性,该属性采用CSS选择器并从响应中选择匹配元素。

您也可以挑选内容以供出去- 的- 通过使用频段交换 HX- 选择- OOB 属性,该属性获取元素ID列表以挑选和交换。

在交换过程中保留内容

如果您希望在互换中保留内容(例如,您希望保持播放的视频播放器 即使发生交换),您也可以使用 HX- 保存 属性属于您要保留的元素。

参数

默认情况下,如果有一个值,则引起请求的元素将包括其值。 如果元素是一种形式 将包括其中所有输入的值。

与HTML形式一样, name 输入的属性用作HTMX发送请求中的参数名称。

另外,如果元素导致非- GET 请求,最近封闭表格的所有输入的值 将包括在内。

如果您想包括其他元素的值,则可以使用 HX- 包括 属性 使用CSS选择器的所有元素,其值要包含在请求中。

如果您想滤除某些参数,则可以使用 HX- 参数 属性。

最后,如果要编程修改参数,则可以使用 htmx:configrequest 事件。

上传文件

如果您想通过HTMX请求上传文件,则可以设置 HX- 编码 属性为 multipart/form-data 。 这将使用 FormData 目的提交请求,该请求将正确包含文件 在请求中。

请注意,取决于您的服务器- 辅助技术,您可能必须非常适合使用这种类型的身体内容的请求 对不同。

请注意,HTMX发射 htmx:xhr:progress 根据标准定期进行活动 progress 上传期间的活动, 您可以挂接以显示上传的进度。

看到 示例部分 对于更高级的形式模式,包括 进度条 错误处理

额外的值

您可以在请求中使用额外的值 HX- 阀 (姓名- 以JSON格式表达对)和 HX- var 属性(逗号- 分开的名称- 动态计算的表达对)。

确认请求

通常,您需要在发出请求之前确认诉讼。 HTMX支持 hx-confirm 属性,它允许您使用简单的JavaScript对话框确认操作:

<button hx-delete= "/account" hx-confirm= "Are you sure you wish to delete your account?" >
Delete My Account
</button>

使用事件,您可以实现更复杂的确认对话框。 这 确认示例 显示如何使用 SweetAlert2 库确认HTMX动作。

属性继承

HTMX中的大多数属性是继承的:它们适用于他们所处的元素以及任何子女元素。 这 允许您 “hoist” 将DOM的属性归为避免代码重复。 考虑以下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 属性。 我们可以将此属性提升到父元素:

<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- 其中有动力的元素。

有时您希望撤消这种继承。 考虑一下我们是否有取消按钮,但不希望它 被确认。 我们可以添加一个 unset 这样的指示:

<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>

然后,顶部两个按钮将显示一个确认对话框,但底部取消按钮不会。

自动继承可以使用 hx-disinherit 属性。

提升

HTMX支持 “boosting” 常规的HTML锚定和形式 HX- 促进 属性。 这 属性将将所有锚标签和表单转换为AJAX请求,默认情况下,该请求针对页面的正文。

这是一个示例:

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

此Div中的锚标签将发行AJAX GET 请求 /blog 并将响应换成 body 标签。

渐进式增强

一个功能 hx-boost 如果不启用JavaScript,它会优雅地退化:链接和表单继续 为了工作,他们根本不使用AJAX请求。 这被称为 渐进式增强 ,它允许 更广泛的受众使用您网站的功能。

其他HTMX模式也可以适应以实现渐进式增强,但它们需要更多的思考。

考虑一下 主动搜索 例子。 正如书写的那样,它不会优雅地降解: 没有启用JavaScript的人将无法使用此功能。 这是为了简单起见的, 保持示例尽可能简短。

但是,您可以包裹HTMX- 增强表单元素的输入:

<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- 启用客户仍然会获得不错的活动- 搜索UX,但非- 启用JavaScript 客户将能够点击Enter密钥并仍在搜索。 更好的是,您可以添加 “Search” 按钮。 然后,您需要用一个 hx-post 这反映了 action 属性,或使用 hx-boost 在上面。

您需要检查服务器端的 HX-Request 标题可以区分HTMX- 驱动和一个 定期请求,确定向客户介绍什么。

可以将其他模式类似地适应以达到应用程序的逐步增强需求。

如您所见,这需要更多的思考和更多的工作。 它还完全符合某些功能。 这些权衡必须由开发人员就项目目标和受众群体进行。

可访问性 是一个概念 与渐进式增强密切相关。 使用进行性增强技术,例如 hx-boost 会让你的 HTMX应用程序更容易被大量用户访问。

htmx- 基于的应用与普通的非正常应用非常相似- AJAX驱动的Web应用程序,因为HTMX为HTML- 定向。

因此,适用正常的HTML可访问性建议。 例如:

*尽可能使用语义HTML(即正确的事物的正确标签) *确保清晰可见焦点状态 *将文本标签与所有表单字段相关联 *使用适当的字体,对比等最大化应用程序的可读性。

Websocket和SSE

HTMX对两者的声明性使用有实验支持 Websocket 服务器发送事件

<div样式= “border: 1px solid whitesmoke; background-color: #e4f0ff; padding: 8px; border-radius: 8px” >

** 笔记:** 在HTMX 2.0中,这些功能将迁移到扩展。 这些新扩展已在 HTMX 1.7+,如果您正在编写新代码,则鼓励您使用扩展名。 所有新功能工作 SSE和Web插座都将在扩展中完成。

请访问 SSE扩展 WebSocket扩展名 页面以了解有关新扩展的更多信息。

Websocket

如果您想建立一个 WebSocket 在HTMX中的连接,您使用 HX- WS 属性:

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

connect 声明建立了联系, send 声明告诉表格将值提交到插座上 submit

可以在 HX- WS属性页

服务器发送事件

服务器发送事件 是服务器将事件发送给浏览器的一种方式。 它提供了更高的- 沟通的水平机制 服务器和浏览器比Websockets。

如果您想通过HTMX响应服务器发送事件的元素,则需要做两件事:

  1. 定义SSE源。 为此,添加一个 HX- SSE 属性在父元素上 A connect:<url> 声明指定将收到服务器发送事件的URL。

  2. 定义元素是该元素的后代,该元素是由服务器发送的事件触发的 hx-trigger="sse:<event_name>" 句法

这是一个示例:

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

根据您的实现,这可能比上面的投票示例更有效,因为服务器将 通知DIV是否有新消息要获得,而不是民意调查引起的稳定要求。

历史支持

HTMX提供了一种与之互动的简单机制 浏览器历史记录API

如果您希望给定的元素将其请求URL推入浏览器导航栏并添加页面的当前状态 对于浏览器的历史,包括 HX- 推- URL 属性:

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

当用户单击此链接时,HTMX将在当前DOM上拍摄并将其存储在请求 /博客之前。 然后,它进行交换并将新位置推到历史堆栈上。

当用户键入后按钮时,HTMX会从存储中检索旧内容并将其交换回目标, 模拟 “going back” 到先前的状态。 如果在缓存中找不到位置,则HTMX将成为AJAX 请求给定URL,并带有标题 HX-History-Restore-Request 设置为true,并期望恢复所需的html 整个页面。 或者,如果 htmx.config.refreshOnHistoryMiss 配置变量设置为true,它将 发出硬浏览器刷新。

** 笔记:** 如果您将URL推入历史,您 ** 必须** 能够导航到该URL并返回完整页面! 用户可以将URL复制并粘贴到电子邮件或新标签中。 此外,HTMX还需要整个页面 历史记录如果页面不在历史记录缓存中。

指定历史记录快照元素

默认情况下,HTMX将使用 body 从中获取并恢复历史记录快照。 这通常是正确的事情,但是 如果要使用较窄的元素进行快照,则可以使用 HX- 历史- 埃尔特 属性以指定另一个。

小心:此元素将需要在所有页面上或从历史记录中恢复无法可靠地工作。

第三方图书馆撤消DOM突变

如果您使用的是第三方库并想使用HTMX历史记录功能,则需要清理DOM 拍摄了快照。 让我们考虑一下 汤姆选择 图书馆,制作精选元素 一种更丰富的用户体验。 让我们设置tomselect以将任何输入元素与 .tomselect class 选择元素。

首先,我们需要初始化具有新内容类的元素:

htmx.onLoad(function (target) {
// find all elements in the new content that should be
// an editor and init w/ quill
var editors = target.querySelectorAll( ".tomselect" )
.forEach(elt => new TomSelect(elt))
});

这将为具有的所有输入元素创建丰富的选择器 .tomselect 上课。 但是,它突变 DOM,我们不希望将这种突变保存到历史缓存中,因为TomSelect将在 历史记录内容已加载回屏幕。

为了解决这个问题,我们需要抓住 htmx:beforeHistorySave 事件并通过打电话清理TomSelect突变 destroy() 在他们:

htmx.on('htmx:beforeHistorySave', function() {
// find all TomSelect elements
document.querySelectorAll('.tomSelect')
.forEach(elt => elt.tomselect.destroy()) // and call destroy() on them
})

这将使DOM还原为原始的HTML,从而允许使用干净的快照。

禁用历史记录快照

可以通过设置历史记录快照来禁用URL HX- 历史 属性为 false 在当前文档中的任何元素上,或HTMX加载到当前文档中的任何HTML片段。 这可以使用 为了防止进入局部孔缓存的敏感数据,这对于共享很重要- 使用 /公共计算机。 历史记录导航将按预期工作,但是在恢复时,将从服务器请求URL,而不是 当地历史记录缓存。

请求&响应

HTMX期望对其提出的AJAX请求做出响应,通常是HTML片段(尽管完整的HTML 文档,与 HX- 选择 标签也可以很有用)。 然后,HTMX将交换返回的 html在指定的目标和掉期策略指定的目标上进入文档。

有时您可能想在互换中什么都不做,但是仍然可以触发客户端事件( 见下文 )。 对于这种情况,您可以退还 204 - No Content 响应代码,HTMX将忽略响应的内容。

如果服务器发生错误响应(例如A 404或A 501),HTMX将触发 htmx:responseError 事件,您可以处理。

如果发生连接错误, htmx:sendError 事件将被触发。

科尔斯

在交叉起源上下文中使用HTMX时,请记住配置您的网络 服务器设置访问- 控制标头,以使HTMX标头可见 在客户端。

请参阅HTMX实施的所有请求和响应标头。

请求标题

HTMX在请求中包含许多有用的标题:

标题描述
HX-Boosted指示该请求是通过元素使用的 HX- 促进
HX-Current-URL当前浏览器的URL
HX-History-Restore-Request”true” 如果在当地历史记录中错过后,请求是要修复历史记录
HX-Prompt用户对 HX- 迅速的
HX-Request总是 “true”
HX-Targetid 目标元素是否存在
HX-Trigger-Namename 触发元素是否存在
HX-Triggerid 触发元素是否存在

响应标题

HTMX支持一些HTMX- 特定响应标头:

  • HX-Location - 允许您做客户- 不做整页重新加载的侧重定向
  • HX-Push-Url - 将新的URL推入历史堆栈
  • HX-Redirect - 可以用来做客户- 侧重定向到新位置
  • HX-Refresh - 如果设置为 “true” 客户端- 一面将全面刷新页面
  • HX-Replace-Url - 替换位置栏中的当前URL
  • HX-Reswap - 允许您指定响应将如何交换。 看 HX- 交换 对于可能的值
  • HX-Retarget - CSS选择器将内容更新的目标更新为页面上的其他元素
  • HX-Reselect - CSS选择器,可让您选择用于交换响应的哪个部分。覆盖现有 hx-select 在触发元素上
  • HX-Trigger - 允许您触发客户端- 附带事件
  • HX-Trigger-After-Settle - 允许您触发客户端- 定居之后的侧事件
  • HX-Trigger-After-Swap - 允许您触发客户端- 交换步骤之后的附带事件

有关更多信息 HX-Trigger 标题,看 HX-Trigger 响应标题

通过HTMX提交表格的好处不再需要 发布/重定向/获取模式 。 成功处理服务器上的发布请求后,您无需返回 HTTP 302(重定向) 。 您可以直接返回新的HTML片段。

请求操作令

HTMX请求中的操作顺序为:

*该元素是触发的,并开始请求 *为请求收集值

  • htmx-request 类应用于适当的元素 *然后通过AJAX异步发出该请求 *得到响应后,目标元素用 htmx-swapping 班级 *应用了可选的掉期延迟(请参阅 HX- 交换 属性) *实际内容交换完成了
  • htmx-swapping 从目标中删除课程
  • htmx-added 班级被添加到每个新内容中
  • htmx-settling 类应用于目标 *完成定居延迟(默认:20ms)
  • DOM已解决
  • htmx-settling 从目标中删除课程
  • htmx-added 从每个新内容中删除课程

您可以使用 htmx-swappinghtmx-settling 创建类 CSS过渡 在页面之间。

验证

HTMX与 HTML5验证API 如果有效的输入无效,则不会发布表格的请求。 Ajax请求以及 Websocket发送。

HTMX触发围绕验证的事件,可用于在自定义验证和错误处理中挂钩:

  • htmx:validation:validate - 在元素之前打电话 checkValidity() 调用方法。 可以用来添加 自定义验证逻辑
  • htmx:validation:failed - 何时呼唤 checkValidity() 返回false,表示输入无效
  • htmx:validation:halted - 由于验证错误而未发出请求时调用。 可能会发现具体错误 在里面 event.detail.errors 目的

非- 表单元素在默认提出请求之前不会验证,但是您可以通过设置启用验证 这 hx-validate 属性为 “true” 。

验证示例

这是使用输入的示例 hx-on 属于捕获 htmx:validation:validate 事件,要求输入具有值 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>

请注意,所有客户端验证都必须重新- 在服务器端完成,因为它们始终可以绕过。

动画

HTMX允许您使用 CSS过渡 在许多情况下,仅使用HTML和CSS。

请看 动画指南 有关可用选项的更多详细信息。

扩展

HTMX具有扩展机制,可允许您自定义库的行为。 扩展 在JavaScript中定义 然后通过 这 hx-ext 属性:

<div hx-ext= "debug" >
<button hx-post= "/example" >This button used the debug extension</button>
<button hx-post= "/example" hx-ext= "ignore:debug" >This button does not</button>
</div>

如果您有兴趣将自己的扩展名添加到HTMX,请 查看扩展文档

包括扩展

HTMX包括一些针对HTMX代码库进行测试的扩展。 这里有几个:

扩大描述
json-enc在请求正文中使用JSON编码,而不是默认 x-www-form-urlencoded
morphdom-swap用于使用的扩展 形态 库作为HTMX中的交换机制。
alpine-morph用于使用的扩展 Alpine.js变形 插件作为HTMX中的交换机构。
client-side-templates支持JSON响应的客户端模板处理
path-deps表达路径的扩展- 基于依赖性 类似于InterCoolerjs
class-tools操纵定时添加和删除html元素的类的扩展
multi-swap允许将多个元素与不同的交换方法交换
response-targets允许将元素与HTTP代码交换以外的响应 200

看到 扩展页面 对于完整的列表。

事件和记录

HTMX有广泛的 事件机制 ,作为记录系统的加倍。

如果要注册给定的HTMX事件,则可以使用

document.body.addEventListener('htmx:load', function(evt) {
myJavascriptLib.init(evt.detail.elt);
});

或者,如果您愿意,可以使用以下HTMX助手:

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

htmx:load 每当元素通过HTMX加载到DOM中时,都会发射事件,并且实际上是等效的 正常 load 事件。

HTMX事件的一些常见用途是:

初始化带有事件的第三方库

使用 htmx:load 初始化内容的事件是如此普遍,以至于HTMX提供了辅助功能:

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

这与第一个示例相同,但更干净。

将请求与事件配置

你可以处理 htmx:configRequest 为了在发出AJAX请求之前修改事件:

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
});

在这里,我们在发送请求之前向其添加了一个参数和标题。

通过事件修改交换行为

你可以处理 htmx:beforeSwap 为了修改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" );
}
});

在这里我们处理一些 400- 级别错误响应代码 这通常不会在HTMX中进行交换。

事件命名

请注意,所有事件均以两个不同的名称发射

  • 骆驼香烟盒 *烤肉串

因此,例如,您可以听 htmx:afterSwaphtmx:after-swap 。 这有助于互操作性 与其他库。 Alpine.js ,例如,需要烤肉串。

记录

如果将记录仪设置为 htmx.logger ,每个活动都将被记录。 这对于故障排除可能非常有用:

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

调试

使用HTMX(或任何其他声明语言)的声明和事件驱动的编程可能是一种很棒且高效的 活动,但是与命令式方法相比,一个缺点是,调试可能更棘手。

例如,如果您不知道这些技巧,弄清楚为什么没有发生 *没有发生 *会很困难。

好吧,这是技巧:

您可以使用的第一个调试工具是 htmx.logAll() 方法。 这将记录HTMX触发的每个事件,并 将允许您确切查看库在做什么。

htmx.logAll();

当然,这不会告诉您为什么HTMX *不 *做某事。 您可能也不知道 * * dom的事件 元素正在触发用作触发器。 为了解决这个问题,您可以使用 monitorEvents() 可用的方法 浏览器控制台:

monitorEvents(htmx.find( "#theElement" ));

这将吐出带有ID上元素上发生的所有事件 theElement 到达控制台,允许您 确切查看它发生了什么。

请注意,此 *仅使用控制台,您无法将其嵌入页面上的脚本标签中。

最后,Push Come推了,您可能只想调试 htmx.js 通过加载未限制的版本。 它是 约2500行JavaScript,因此不是无法克服的代码。 您很可能想休息一下 指向 issueAjaxRequest()handleAjaxResponse() 查看发生了什么的方法。

并总是随意跳上 不和谐 如果你需要帮助。

创建演示

有时,为了演示错误或澄清用法,能够使用JavaScript片段是很高兴的 网站喜欢 JSFIDDLE 。 为了促进简单的演示创建,HTMX托管了演示脚本 将安装的网站:

  • htmx *超级标题 *请求嘲笑库

只需将以下脚本标签添加到您的演示/小提琴/其他:

<script src= "https://demo.htmx.org" ></script>

这个助手允许您通过添加模拟响应来添加模拟响应 template 带有A的标签 url 属性指示哪个URL。 该URL的响应将是模板的InnerHTML,使构造模拟响应变得容易。 你可以 用一个 delay 属性,该属性应该是指示毫秒数的整数 延迟

您可以将简单的表达式嵌入模板中 ${} 句法。

请注意,这仅应用于演示,绝对不保证长时间工作 因为它将始终抓住最新版本的HTMX和Hyperscript!

演示示例

这是行动中代码的示例:

<!-- 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>

脚本

虽然HTMX鼓励HyperMedia构建Web应用程序的方法,但它提供了许多用于客户脚本的选项。 其余的脚本包含- Web体系结构的最佳描述,请参阅: 代码- 在- 要求 。 尽可能可行,我们建议 超媒体- 友好的 在您的Web应用程序中进行脚本的方法:

HTMX和脚本解决方案之间的主要集成点是 事件 HTMX发送的,可以 回应。 在 第三方JavaScript 为一个好模板的部分 通过事件将JavaScript库与HTMX集成。

与HTMX配对的脚本解决方案包括:

  • 香草 - 简单地使用构建- 在JavaScript的能力中,在事件处理程序中挂钩 响应事件HTMX发射可以很好地用于脚本。 这是一个非常轻巧的,越来越多的 流行的方法。
  • Alpinejs - Alpine.js提供了一套丰富的工具来创建复杂的前端脚本, 包括反应性编程支持,同时仍然保持极轻。 高山鼓励 “inline scripting” 我们感觉与HTMX配对的方法。
  • jQuery - 尽管在某些圈子中的年龄和声誉,但与HTMX配对非常好,尤其是 在较旧的代码中- 已经有很多jQuery的基地。
  • 超级标题 - Hyperscript是一个实验前线- 结束脚本语言由同一语言创建 创建HTMX的团队。 它旨在很好地嵌入HTML,并且既响应并创建事件,并且配对很好 与HTMX。

我们有整章题为 “Client-Side Scripting” 在我们的 图书](https://hypermedia.systems),研究如何将脚本集成到您的HTMX中- 基于应用。

hx-on 属性

HTML允许通过 onevent 特性 ,,,, 例如 onClick

<button onclick= "alert('You clicked me!')" >
Click Me!
</button>

此功能允许脚本逻辑成为合作- 带有逻辑适用的HTML元素,提供良好 行为的位置(LOB) 。 不幸的是,HTML仅允许 on* 固定的属性 数量 特定的DOM事件 (例如。 onclick ) 和 不提供对元素上任意事件做出响应的广义机制。

为了解决这个缺点,HTMX提出 hx-on* 属性。 这些属性允许 您以保留标准块的方式对任何事件做出回应 on* 特性。

如果我们想回应 click 使用a的事件 hx-on 属性,我们会写这件:

<button hx-on:click= "alert('You clicked me!')" >
Click Me!
</button>

所以,字符串 hx-on ,然后是结肠(或破折号),然后是事件的名称。

为一个 click 事件当然,我们建议坚持使用标准 onclick 属性。 但是,考虑一个 htmx- 希望使用该按钮将参数添加到请求中 htmx:config-request 事件。 这不会 可以使用标准 on* 属性,但可以使用 hx-on:htmx:config-request 属性:

<button hx-post= "/example"
hx-on:htmx:config-request= "event.detail.parameters.example = 'Hello Scripting!'" >
Post Me!
</button>

在这里 example 参数已添加到 POST 在发出之前请求“您好脚本!”。

hx-on* 属性是通用嵌入式脚本的非常简单的机制。 它是_not_的替代品 完全开发的前线- 结束脚本解决方案,例如Alpinejs或Hyperscript。 但是,它可以增加香草- 基于 在您的htmx中脚本的方法- 电力应用。

请注意,html属性是 *案例不敏感 *。 这意味着不幸的是,依靠大写的事件/ 骆驼套,无法回应。 如果您需要支持骆驼案件,我们建议您更全面地使用 功能脚本解决方案,例如Alpinejs或Hyperscript。 HTMX在骆驼和中都派遣了所有事件 烤肉串- 出于这个原因。

第三方JavaScript

HTMX与第三方库相当完善。 如果图书馆在DOM上发射事件,您可以使用这些事件来 触发来自HTMX的请求。

一个很好的例子是 sortablejs演示

<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库一样,您需要在某个时候初始化内容。

在jQuery中,您可能会这样做:

$(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 功能,您只能从新加载的内容中选择 而不是整个文档:

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时,可排序的元素被正确初始化。

如果JavaScript将内容添加到其中具有HTMX属性的DOM,则需要确保此内容 用 htmx.process() 功能。

例如,如果您要获取一些数据并将其放入DIV中 fetch API,而HTML有 其中HTMX属性,您需要将调用添加到 htmx.process() 像这样:

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 函数要查找将触发条件内容的价值变化:

<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>

缓存

HTMX与标准配合使用 HTTP缓存 开箱即用的机制。

如果您的服务器添加 Last-Modified http响应标题对给定URL的响应,浏览器将自动添加 If-Modified-Since 请求HTTP标头到下一个请求到同一URL。 注意如果 您的服务器可以根据其他一些其他内容呈现不同的内容 标题,您需要使用 Vary 响应HTTP标头。 例如,如果您的服务器呈现完整的HTML HX-Request 标头丢失或 false ,并且它呈现出HTML的片段 什么时候 HX-Request: true ,您需要添加 Vary: HX-Request 。 这导致缓存是 基于响应URL和 HX-Request 请求标题 - 而不是仅基于响应URL。

如果您无法(或不愿意)使用 Vary 标题,您可以选择设置配置参数 getCacheBusterParamtrue 。 如果设置了此配置变量,则HTMX将包括一个缓存- 破坏参数 在 GET 它提出的要求,这将阻止浏览器缓存HTMX- 基于和非- 基于HTMX的响应 在同一缓存插槽中。

HTMX也可以使用 ETag 正如预期的。 请注意,如果您的服务器可以呈现不同的内容 URL(例如,取决于 HX-Request 标题),服务器需要 生成不同的 ETag 每个内容。

安全

HTMX允许您直接在DOM中定义逻辑。 这有许多优势,最大的是 行为的局部性 ,这使您的系统易于理解和 维持。

但是,对这种方法的关注是安全性:因为HTMX会提高HTML的表现力,如果是恶意的话 用户能够将HTML注入您的应用程序,他们可以利用HTMX的这种表达性 结束。

规则1:逃脱所有用户内容

HTML的第一个规则- 基于Web开发一直是: *不信任用户的输入 *。 你应该逃脱所有 第三方,不受信任的内容注入您的网站。 这是为了防止,除其他问题外, XSS攻击

关于XSS有广泛的文档以及如何在优秀上预防它 Owasp网站 ,,,, 包括 跨站点脚本预防备忘单

好消息是,这是一个非常古老且知识渊博的话题,并且绝大多数服务器- 侧模板语言 支持 自动逃脱 的 满足此问题的内容。

话虽这么说,有时人们会选择更危险地注入HTML,通常是通过某种形式的 raw() 其模板语言中的机制。 这可以是有充分理由这样做的,但是如果注入内容即将到来 从第三方开始,然后将其擦洗,包括删除以开头的属性 hx-data-hx , 也 排队 <script> 标签等

如果您要注入生HTML并进行自己的逃脱,最好的做法是 *白名单 *属性和标记您 允许,而不是将您禁止的列表列入列表。

HTMX安全工具

当然,错误发生,开发人员并不完美,因此最好有一种分层的安全方法 您的Web应用程序和HTMX提供了帮助您确保应用程序的工具。

让我们看一下他们。

hx-disable

HTMX提供的第一个工具以帮助您进一步保护您的应用程序是 hx-disable 属性。 此属性将防止给定元素上的所有HTMX属性处理,以及 它。 因此,例如,如果您在模板中加入了RAW HTML内容(再次不建议!),那么您 可以用 hx-disable 属性:

<div hx-disable>
<%= raw(user_content) %>
</div>

HTMX不会处理任何HTMX- 该内容中找到的相关属性或功能。 这个属性不能是 通过注入更多内容来禁用:如果 hx-disable 属性是在父母层次结构中的任何地方找到的 元素,它不会由HTMX处理。

hx-history

另一个安全考虑是HTMX历史缓存。 您可能有没有敏感数据的页面 想要存储在用户中 localStorage 缓存。 您可以通过包括历史记录缓存中的给定页面 hx-history 属性页面上的任何位置,并将其值设置为 false

配置选项

HTMX还提供与安全有关的配置选项:

  • htmx.config.selfRequestsOnly - 如果设置为 true ,仅允许对当前文档的同一域请求
  • htmx.config.allowScriptTags - HTMX将处理 <script> 在新内容中找到的标签加载。 如果您想禁用 此行为您可以将此配置变量设置为 false
  • htmx.config.historyCacheSize - 可以设置为 0 避免将任何HTML存储在 localStorage 缓存
  • htmx.config.allowEval - 可以设置为 false 禁用依赖于评估的HTMX的所有功能: *事件过滤器
  • hx-on: 属性
  • hx-valsjs: 字首
  • hx-headersjs: 字首

请注意,通过禁用删除的所有功能 eval() 可以使用您自己的自定义JavaScript和 HTMX事件模型。

事件

如果要允许请求到当前主机以外的某些域,但不要完全打开,您可以 使用 htmx:validateUrl 事件。 此事件将在此处提供请求URL detail.url 插槽 作为一个 sameHost 财产。

您可以检查这些值,如果请求无效,请调用 preventDefault() 在活动中以防止 发出的请求。

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选项

浏览器还提供了进一步保护您的Web应用程序的工具。 可用的最强大工具是 内容安全策略 。 使用CSP,您可以告诉 例如,浏览器不向非- 原始主机,不评估内联脚本标签,等等。

这是一个示例CSP meta 标签:

<meta http-equiv= "Content-Security-Policy" content= "default-src 'self';" >

这告诉浏览器 “Only allow connections to the original (source) domain” 。 这将是多余的 htmx.config.selfRequestsOnly ,但是有必要采用分层的安全方法,实际上是理想的 使用应用程序安全。

对CSP的完整讨论超出了本文档的范围,但是 MDN文章 提供一个良好的起点 用于探索这个话题。

配置HTMX

HTMX具有一些可以通过编程或声明性访问的配置选项。 他们是 下面列出:

配置变量信息
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对某些功能的使用(例如触发过滤器)
htmx.config.allowScriptTags默认为 true ,确定HTMX是否会处理新内容中的脚本标签
htmx.config.inlineScriptNonce默认为 '' ,这意味着不会将nonce添加到内联脚本
htmx.config.attributesToSettle默认为 ["class", "style", "width", "height"] ,在定居阶段定居的属性
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默认为“平滑”,这是页面过渡上增强链接的行为。 允许的值是 autosmooth 。 平滑将平滑滚动到页面顶部,而自动的表现就像香草链接一样。
htmx.config.defaultFocusScroll如果应将重点元素滚动到视图中,则默认为false,可以使用 重点- 滚动 交换修饰符。
htmx.config.getCacheBusterParam默认为false,如果设置为true HTMX会将目标元素附加到 GET 要求格式 org.htmx.cache-buster=targetElementId
htmx.config.globalViewTransitions如果设置为 true ,HTMX将使用 查看过渡 交换新内容时的API。
htmx.config.methodsThatUseUrlParams默认为 ["get"] ,HTMX将通过在URL中编码其参数,而不是请求主体来格式化请求。
htmx.config.selfRequestsOnly默认为 false ,如果设置为 true 将仅允许AJAX请求与当前文档相同的域
htmx.config.ignoreTitle默认为 false ,如果设置为 true HTMX将不会更新文档的标题 title 标签在新内容中找到
htmx.config.scrollIntoViewOnBoost默认为 true ,是否将增强元素的目标滚动到视口中。 如果 hx-target 在增强元素上省略了,目标默认为 body ,导致页面滚动到顶部。
htmx.config.triggerSpecsCache默认为 null ,用于存储评估的触发规格的缓存,以更多的内存使用成本改善解析性能。 您可以定义一个简单的对象以使用永不- 清除缓存,或使用一个 代理对象

您可以将它们直接设置在JavaScript中,也可以使用 meta 标签:

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

结论

就是这样!

与HTMX玩得开心! 你可以完成 很多 没有编写很多代码!