You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Bootstrap、Thymeleaf或JS实现嵌套展开折叠?解决联动折叠问题

解决Bootstrap + Thymeleaf多层折叠面板父子同时折叠的问题

嘿,我刚梳理了你的问题,这种多层嵌套折叠时父子容器同时触发折叠的情况很常见,核心原因集中在事件冒泡、重复ID冲突和data-parent配置范围错误这三点,咱们一步步来解决:

问题根源拆解

  1. 事件冒泡:你给父级和子级的<li>都绑定了data-toggle="collapse",点击子级时,事件会向上冒泡到父级元素,触发父级的折叠逻辑。
  2. 重复ID:代码里每个Provisions项下面都用了<div id="accordion-sub">,但ID是全局唯一的标识,重复的ID会让Bootstrap的JS逻辑混乱,无法精准定位折叠容器。
  3. data-parent范围错误:子级的data-parent="#accordion-sub"指向的是重复的固定ID,没有和当前父折叠项绑定,导致折叠行为串层。

针对性解决方案

1. 给子级折叠项添加事件阻止冒泡

在子级的<li>上添加onclick="event.stopPropagation()",阻止点击事件向上传递到父级元素,这样点击子级时就不会触发父级的折叠动作了。

2. 生成全局唯一的容器ID

利用Thymeleaf的循环索引给每个子折叠容器生成唯一ID,比如把id="accordion-sub"改成th:attr="id='accordion-sub-'+${indexObj.index}",确保每个Provisions项下面的子容器ID不重复。

3. 修正data-parent的指向

子级折叠项的data-parent要指向当前Provisions项对应的唯一子容器ID,而不是固定的#accordion-sub,确保折叠行为只在当前层级生效。

修改后的完整代码示例

<!-- 州层级的根折叠容器,id="accordion" -->
<ul id="accordion" style="list-style-type: none;">
    <li data-toggle="collapse" data-parent="#accordion" aria-expanded="false" aria-controls="Provisions"
        th:each="ProvisionsName,indexObj : ${ProvisionsNames}"
        th:attr="data-target='#Provisions'+${indexObj.index}">
        <span data-feather="plus-circle"></span>
        <span th:text="${ProvisionsName}"></span>
        <div class="collapse in" th:attr="id='Provisions'+${indexObj.index}">
            <div>
                <ul style="list-style-type: none;">
                    <li th:each="ProvisionsList : ${ProvisionsMap.get(ProvisionsName)}">
                        <span th:text="${ProvisionsList}"></span><br>
                        <label><strong>Provisions :</strong></label>
                        <span th:text="${ProvisionsName}"></span>
                        <!-- 生成唯一的子折叠容器ID -->
                        <div th:attr="id='accordion-sub-'+${indexObj.index}">
                            <ul style="list-style-type: none;">
                                <li data-toggle="collapse" aria-expanded="false"
                                    <!-- 动态绑定当前层级的data-parent -->
                                    th:attr="data-parent='#accordion-sub-'+${indexObj.index}, data-target='#Mandals'+${indexObj.index}+'-'+${indexObjs.index}"
                                    th:each="MandalsName,indexObjs : ${ProvisionsMandalsMap.get(ProvisionsName)}"
                                    onclick="event.stopPropagation()"> <!-- 阻止事件冒泡 -->
                                    <span data-feather="plus-circle"></span>
                                    <span th:text="${MandalsName}"></span>
                                    <!-- 生成唯一的Mandals折叠内容ID -->
                                    <div class="collapse in" th:attr="id='Mandals'+${indexObj.index}+'-'+${indexObjs.index}">
                                        <ul style="list-style-type: none;">
                                            <li th:each="MandalsList : ${MandalsMap.get(MandalsName)}">
                                                <span th:text="${MandalsList}"></span>
                                            </li>
                                        </ul>
                                    </div>
                                </li>
                            </ul>
                        </div>
                    </li>
                </ul>
            </div>
        </div>
    </li>
</ul>

关键修改点说明

  • event.stopPropagation():拦截子级点击事件的向上传递,避免触发父级<li>的折叠逻辑。
  • 动态唯一ID:通过${indexObj.index}和${indexObjs.index}组合生成accordion-sub-xxx和Mandals-xxx-xxx,确保页面中所有ID唯一,Bootstrap能精准定位目标容器。
  • data-parent动态绑定:子级折叠项的data-parent指向当前Provisions项对应的子容器,让折叠行为被限制在当前层级,不会影响父级或其他平行层级。

这样修改后,点击子级的Mandals折叠项时,就只会展开/折叠自身内容,父级的Provisions折叠状态不会再被误触发了。

内容的提问来源于stack exchange,提问作者HaniHari

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 07:51:28