ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

htmx 的 hx-indicator 属性:用 htmx-request 类实现请求进行中的加载指示器

htmx 的 hx-indicator 属性:用 htmx-request 类实现请求进行中的加载指示器 前端【免费下载链接】htmxhtmx - high power tools for HTML项目地址https://gitcode.com/GitHub_Trending/ht/htmx点击查看免费下载hx-indicator是 htmx 中用于在请求AJAX 请求进行期间向指定元素添加htmx-request类的属性它让你可以用极少的代码为按钮、表单或任意交互元素挂载加载动画spinner / progress indicator。本文以 hx-indicator.md 为核心结合 htmx.js 的源码实现与 hx-indicator.js 测试用例完整讲解该属性的选择器语法、closest/inherit关键字、默认样式与自定义样式、相关配置项includeIndicatorStyles、inlineStyleNonce等及其底层工作原理帮助你写出可复用的加载态交互。一、hx-indicator 是什么hx-indicator允许你指定一个或多个元素在请求存活期间request in flight为它们添加htmx-request类。通过配合默认注入的 CSS这些元素可以在请求期间显示为可见例如旋转的 spinner请求结束后自动隐藏。该属性的值有两种形式CSS 查询选择器指定一个或多个要应用htmx-request类的元素closest关键字closest后跟一个 CSS 选择器例如closest tr会找到「自身或最近的匹配该选择器的祖先元素」并应用类。一个最简单的例子——把 spinner 放在按钮旁边div button hx-post/example hx-indicator#spinner Post It! /button img idspinner classhtmx-indicator src/img/bars.svg altLoading.../ /div当请求发起时htmx 会把htmx-request类加到#spinner图片上图片自身带有的htmx-indicator类配合默认 CSS 定义了透明度过渡从而让 spinner 显示出来。二、选择器语法CSS 选择器与 closest 关键字hx-indicator的值是一个 CSS 查询选择器因此你可以灵活指向任意元素指向单个元素hx-indicator#spinner指向多个元素hx-indicator#a1, #a2逗号分隔的 CSS 选择器列表使用相对选择器如hx-indicatornext a从触发元素出发按 htmx 的扩展选择器语法定位目标使用closest关键字hx-indicatorclosest tr会找到按钮自身或最近的tr祖先并应用类从源码看选择器解析发生在 findAttributeTargets 函数中它先通过getClosestAttributeValue取得最近的hx-indicator属性值然后调用querySelectorAllExt解析扩展选择器支持this、closest、next等 htmx 扩展语法。若选择器没有任何匹配htmx 会记录错误日志「The selector ... on hx-indicator returned no matches!」并退回使用一个占位元素DUMMY_ELT避免请求流程中断。三、默认 htmx-indicator 样式与显示原理当请求在飞行中时htmx 会把htmx-request类添加到#spinner图片上。图片还带有htmx-indicator类该类定义了使 spinner 显示出来的透明度过渡.htmx-indicator { opacity: 0; visibility: hidden; } .htmx-request .htmx-indicator, .htmx-request.htmx-indicator { opacity: 1; visibility: visible; transition: opacity 200ms ease-in; }这套默认 CSS 的特点值得注意visibility: hidden而非仅opacity: 0隐藏状态下的指示器对屏幕阅读器也是不可见的保证了更好的无障碍accessibility表现快速淡入transition: opacity 200ms ease-in让 spinner 出现时有 200ms 的柔和淡入效果两种选择器形态.htmx-request .htmx-indicator覆盖「指示器是请求元素的子孙」的情形.htmx-request.htmx-indicator覆盖「指示器元素本身携带htmx-request类」的情形例如hx-indicatorthis时。这套默认样式并不是手写在页面里的——htmx 在初始化时会自动将其注入到head中。对应实现位于 insertIndicatorStylesgetDocument().head.insertAdjacentHTML(beforeend, style${nonceAttribute} .${indicator}{opacity:0;visibility: hidden} .${request} .${indicator}, .${request}.${indicator}{opacity:1;visibility: visible;transition: opacity 200ms ease-in} /style )注入的样式使用htmx.config.indicatorClass默认htmx-indicator和htmx.config.requestClass默认htmx-request动态拼接因此当你修改这两个配置项时自动注入的 CSS 会跟着适配。四、自定义指示器样式如果你希望使用不同的显示效果例如用display而非透明度可以定义并使用自己的指示器 CSS。此时建议改用自定义类名如my-indicator避免与默认注入的htmx-indicator样式互相干扰.my-indicator { display: none; } .htmx-request .my-indicator, .htmx-request.my-indicator { display: inline; }对应的 HTML 里将 spinner 的类改为my-indicator即可div button hx-post/example hx-indicator#spinnerPost It!/button img idspinner classmy-indicator src/img/bars.svg altLoading.../ /div演示效果可以参考文档中的 Demo 片段用classestoggle htmx-request:3s模拟 3 秒请求期间的显示状态button classbtn classestoggle htmx-request:3s Post It! img classhtmx-indicator src/img/bars.svg altLoading.../ /button五、inherit 关键字继承父级指示器并叠加hx-indicator是可继承的属性可以放在父元素上作用于其内部的所有请求。更灵活的是你还可以在子元素上用inherit关键字显式「继承父级的值」并在其后追加额外的指示器选择器main hx-indicator#global-indicator ... button hx-post/example hx-indicatorinherit, #spinner Post It! /button img idspinner classhtmx-indicator src/img/bars.svg altLoading.../ /main这里按钮的hx-indicatorinherit, #spinner表示既继承父级main上的#global-indicator又叠加本地的#spinner请求期间两者都会获得htmx-request类。源码层面inherit的判定逻辑同样在 findAttributeTargets 中它用正则/(^|,)(\s*)inherit(\s*)($|,)/检查属性值中是否出现「被逗号包围或位于首尾的独立单词inherit」若命中则向上查找最近的、带有同名属性的祖先元素并递归调用findAttributeTargets合并其结果。六、指示器目标可以是父层级中的任意元素hx-indicator选择器指向的目标不必是你要显示的那个元素本身——它可以是该指示器父层级祖先链中的任意元素。例如button hx-post/example hx-indicatorclosest div Post It! /button请求期间htmx-request类会加到按钮最近的div祖先上只要你自己的 CSS 规则如.htmx-request .htmx-indicator能覆盖到该 div 内部的指示器元素spinner 依然能正常显示。这使得指示器可以与触发元素解耦实现「高亮整行、整卡片或整个表单区域」等更丰富的视觉效果。七、默认行为不写 hx-indicator 也能用需要特别说明的是在缺少显式hx-indicator时htmx-request类默认会添加到触发请求的那个元素本身。因此你可以把指示器直接放进触发元素内部完全不需要声明hx-indicator属性button hx-post/example Post It! img classhtmx-indicator src/img/bars.svg altLoading.../ /button对应的实现位于 addRequestIndicatorClasses它调用findAttributeTargets(elt, hx-indicator)解析显式指示器如果解析结果为空则回退为indicators [elt]即把触发元素本身当作指示器。八、源码级原理请求计数与类名生命周期htmx-request类的添加与移除并非简单的「加一次、减一次」而是通过请求计数requestCount保证并发请求下的正确性。请求发起时addRequestIndicatorClasses 对每个指示器元素执行internalData.requestCount (internalData.requestCount || 0) 1 addClassToElement(ic, htmx.config.requestClass)即每发起一个请求目标指示器元素的requestCount加 1并添加htmx-request类。该函数的返回值indicators会被传递给后续的请求处理流程ajax 主流程 中的多处调用点以便在请求结束成功、错误、中止、超时等所有分支时统一清理。请求结束时removeRequestIndicators 执行反向操作internalData.requestCount (internalData.requestCount || 1) - 1 // 仅当计数归零时才移除类 if (internalData.requestCount 0) { removeClassFromElement(ic, htmx.config.requestClass) }这意味着多个并发请求共享同一个指示器时只要还有任意一个请求未完成指示器就会保持显示状态只有所有请求都结束时htmx-request类才会被移除。这一行为在 test/attributes/hx-indicator.js 中有专门的测试用例覆盖两个按钮共享.a1指示器依次触发请求后仅当两个响应都处理完毕指示器类才被移除。此外class-cleanup.js 中的测试验证了另一个细节请求完成后若指示器原本没有class属性htmx 会将其彻底移除而不是留下一个空的class保持 DOM 干净。九、相关配置项与 CSP 注意事项hx-indicator涉及的配置项均定义在 htmx.js 的 config 段可通过meta namehtmx-config或htmx.config修改配置项默认值作用includeIndicatorStylestrue是否自动向页面注入指示器默认 CSS。设为false可完全禁用自动注入indicatorClasshtmx-indicator指示器元素使用的类名配合默认 CSS 生效requestClasshtmx-request请求进行中添加到触发元素/指示器元素上的类名inlineStyleNonce无自动注入style标签时附加的 nonce 值用于满足基于 nonce 的 CSP 策略9.1 禁用自动注入的指示器样式如果你希望使用自己的 CSS、但仍保留htmx-indicator作为类名需要禁用includeIndicatorStyles否则自动注入的默认样式会与你的样式冲突。最简单的方式是在 HTML 的head中添加meta namehtmx-config content{includeIndicatorStyles: false}禁用后你需要在自己的 CSS 文件中提供一份htmx-indicator样式可参考前文第三节或第四节的写法。9.2 strict nonce 型 CSP当includeIndicatorStyles未被禁用时htmx 注入的指示器样式使用内联style标签。如果你的站点采用严格的 nonce 型 CSPstyle-src要求 nonce需要设置inlineStyleNonce配置使注入的style携带 noncemeta namehtmx-config content{inlineStyleNonce: random-nonce}对应实现可见 insertIndicatorStylesconst nonceAttribute htmx.config.inlineStyleNonce ?nonce${htmx.config.inlineStyleNonce}: nonce 会拼进注入的style标签属性中。9.3 完全禁止内联样式的 CSP如果你的 CSP 需要阻止所有内联style标签例如style-src不允许unsafe-inline也不允许 nonce那么唯一的选择是禁用includeIndicatorStyles自行托管一份包含htmx-indicator样式的 CSS 文件并在页面中通过合法的外部样式表引入。十、测试验证与行为清单test/attributes/hx-indicator.js 使用 Mocha Sinon fake server 对hx-indicator的行为做了系统性验证可作为实现行为的事实依据无显式指示器htmx-request类添加到触发元素本身响应后移除第 11-18 行显式多目标选择器hx-indicator#a1, #a2时htmx-request添加到两个目标元素、而非按钮第 20-33 行相对选择器hx-indicatornext a定位下一个a元素第 35-45 行data-前缀*data-hx-indicator与hx-indicator行为一致第 47-60 行closest 语法hx-indicatorclosest div将类加到最近的div祖先第 62-72 行this 语法hx-indicatorthis将类加到携带属性的元素自身第 85-95 行并发共享指示器多个请求共享同一指示器时计数归零才移除类第 97-120 行。小结hx-indicator的核心设计思路非常简洁用一个类htmx-request在请求期间标记目标元素配合 CSS 完成显隐切换。理解其选择器语法CSS 选择器、closest、this、inherit叠加、默认样式注入机制includeIndicatorStyles与inlineStyleNonce以及基于requestCount的并发计数清理逻辑你就能在任意 htmx 应用中稳定、无障碍地实现加载指示效果并从容应对严格 CSP 等复杂环境。赞分享前端【免费下载链接】htmxhtmx - high power tools for HTML项目地址https://gitcode.com/GitHub_Trending/ht/htmx点击查看免费下载相关推荐svg2pdf.js高级功能解析渐变、图案和自定义字体处理终极指南svg2pdf.js高级功能解析渐变、图案和自定义字体处理终极指南 svg2pdf.js是一个强大的纯JavaScript工具能够在浏览器中将SVG矢量图形新范式思维架构Qwen3-235B-A22B-Thinking-2507-FP8未来发展方向新范式思维架构Qwen3 235B A22B Thinking 2507 FP8未来发展方向 Qwen3 235B A22B Thinking 2507 FP大模型深度学习if和while是如何被编译的miniC-hosting可视化JMP与JZ控制流指令if和while是如何被编译的miniC hosting可视化JMP与JZ控制流指令 你有没有好奇过 if 和 while 这样平平无奇的语句到了计算机底上一篇深入 Astryx Vibe Tests用结构化 LLM 基准评测设计系统的 Agent 就绪度下一篇Code Review: [PR Title]创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表