htmx head 支持扩展

head-support 扩展增加了对 htmx 请求响应中的 head 标签的支持。

htmx 最初是一个专注于 body 部分替换标签内的 HTML 的库。因此,合并诸如 head 标签之类的附加信息并不是该库的重点。(这与 TurboLinks 等库不同,后者专注于将通过 AJAX 检索到的整个网页合并到浏览器中。)

hx-boost属性使 htmx 更接近于完全支持 HTML 文档的世界,并且最终添加了从 head 元素中提取 title 标签的支持,但完全支持 head 标签从未成为该库的功能。此扩展解决了这一缺点。

安装

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

用法

<body hx-ext="head-support">
...
</body>

安装此功能后,htmx 收到的所有包含 head 标签的响应(即使它们不是具有根 <html> 元素的完整 HTML 文档)都将被处理。

如何处理 head 标签取决于 htmx 请求的类型。

如果请求来自 htmx 增强元素,则使用以下合并算法:

  • 当前头部中存在的精确文本匹配的元素将保留在原处
  • 当前 head 中不存在的元素将被添加在 head 标签的末尾
  • 存在于当前头部但不存在于新头部的元素将从头部中删除

如果 htmx 请求来自非提升元素,则所有内容都将附加到现有的头元素。

如果你希望在任何一种情况下覆盖此行为,则可以将hx-head属性放在新 <head> 标签上,并使用以下两个值之一:

  • merge - 遵循上述的合并算法
  • append - 将元素附加到现有的头部

控制合并行为

除此之外,你还可以使用以下属性控制各个元素的合并行为:

  • 如果你将 hx-head="re-eval" 放置在 head 元素上,则即使它已经存在,也会在每个请求中将其重新添加(删除并附加)到 head 标记。这对于在每个 htmx 请求上执行脚本非常有用。
  • 如果你放置 hx-preserve="true" 在某个元素上,它将永远不会从头部移除

例子

举例来说,考虑现有文档中的以下 head 标签:

<head>
<link rel="stylesheet" href="https://the.missing.style">
<link rel="stylesheet" href="/css/site1.css">
<script src="/js/script1.js"></script>
<script src="/js/script2.js"></script>
</head>

如果 htmx 收到包含此新 head 标签的请求:

<head>
<link rel="stylesheet" href="https://the.missing.style">
<link rel="stylesheet" href="/css/site2.css">
<script src="/js/script2.js"></script>
<script src="/js/script3.js"></script>
</head>

然后会发生下面的操作:

<link rel="stylesheet" href="https://the.missing.style"> 将会单独保留 <link rel="stylesheet" href="/css/site1.css"> 将被从头部移除 <link rel="stylesheet" href="/css/site2.css"> 将被添加到头部 <script src="/js/script1.js"></script> 将被从头部移除 <script src="/js/script2.js"></script> 将会单独保留 <script src="/js/script3.js"></script> 将被添加到头部

最终的 head 元素将如下所示:

<head>
<link rel="stylesheet" href="https://the.missing.style">
<script src="/js/script2.js"></script>
<link rel="stylesheet" href="/css/site2.css">
<script src="/js/script3.js"></script>
</head>

事件

此扩展会触发以下事件:

  • htmx:removingHeadElement - 当头元素即将被移除时触发,元素将会在 event.detail.headElement 中被移除。如果 preventDefault() 在事件上调用,则不会移除元素。
  • htmx:addingHeadElement - 在即将添加头元素时触发,元素将会在 event.detail.headElement 被添加。如果 preventDefault() 在事件上调用 ,则不会添加元素。
  • htmx:afterHeadMerge - 在发生头标签合并后触发,事件中可用的值如下detail:
  • added - 添加了头部元素
  • kept - 保留头部元素
  • removed - 删除了头部元素
  • htmx:beforeHeadMerge - 在头部合并发生之前触发