Htmx多元素页面中hx-indicator如何选择最近加载Spinner?
问题:Htmx中如何为单个元素绑定最近的加载Spinner?
页面存在多个同类表单元素,使用Htmx触发请求时希望仅显示当前元素最近的Spinner,且复用Spinner片段(不使用顺序ID)。尝试hx-indicator="closest .htmx-indicator"时出现JavaScript错误:htmx.min.js:1 Uncaught TypeError: Cannot read properties of null (reading 'htmx-internal-data'),而closest div选择范围过宽,需要正确的选择器写法。
当前实现代码
<div class="col-4 px-4dot5 py-3 bg-secondary-light"> <label for="stellenangebotLink" class="form-label fs-5">Link</label> <div id="linkHelpBlock">E-Mail-Adresse oder Website-URL</div> <?= $this->include('components/_htmx_spinner') ?> <input hx-post="/medien/personal-kampagne/stellenangebot-modal/link" hx-trigger="keyup changed delay:300ms" hx-include="#stellenangebot_id" hx-target="#stellenangebotLinkWrapper" hx-indicator=".htmx-indicator" name="link" id="stellenangebotLink" class="form-control" aria-describedby="linkHelpBlock"> </div>
Spinner代码
<div id="spinner" class="spinner-border spinner-border-sm mx-2 htmx-indicator" role="status"> <span class="visually-hidden">Loading...</span> </div>
解决方案
错误原因说明
使用closest .htmx-indicator出错是因为closest()方法仅向上查找父级元素,而当前Spinner是输入框的同级元素,无法被closest()定位,导致Htmx找不到目标元素抛出空指针错误。
方案一:利用同级元素选择器(推荐,无需修改DOM结构)
因为Spinner是输入框的紧前兄弟元素,直接使用Htmx支持的previousElementSibling相对选择器定位:
修改输入框的hx-indicator属性:
hx-indicator="previousElementSibling.htmx-indicator"
这种写法精准定位当前输入框的前一个同级Spinner元素,不会影响页面其他同类组件。
方案二:通过父容器限定范围(适用于DOM结构灵活调整的场景)
如果Spinner和输入框的同级关系可能变化,可以将两者包裹在同一个父容器内,通过父容器缩小选择范围:
修改后的DOM结构:
<div class="col-4 px-4dot5 py-3 bg-secondary-light"> <label for="stellenangebotLink" class="form-label fs-5">Link</label> <div id="linkHelpBlock">E-Mail-Adresse oder Website-URL</div> <!-- 新增父容器包裹Spinner和输入框 --> <div class="input-wrapper"> <?= $this->include('components/_htmx_spinner') ?> <input hx-post="/medien/personal-kampagne/stellenangebot-modal/link" hx-trigger="keyup changed delay:300ms" hx-include="#stellenangebot_id" hx-target="#stellenangebotLinkWrapper" <!-- 先找最近的父容器,再在容器内查找Spinner --> hx-indicator="closest .input-wrapper .htmx-indicator" name="link" id="stellenangebotLink" class="form-control" aria-describedby="linkHelpBlock"> </div> </div>
内容的提问来源于stack exchange,提问作者Simon Weber
相关产品推荐
相关产品推荐

