Blade模板循环列表点击仅切换对应项,触发所有条目切换如何解决
问题原因
- 你当前的逻辑是全局修改
.show类的CSS样式规则,所有匹配该类的元素会同步应用样式,自然会触发所有条目一起切换 - 全局唯一的
isHidden变量共享了所有条目的显隐状态,无法区分不同条目的独立状态 - 每次点击都往页面插入新的style标签,会产生大量冗余DOM,存在性能问题
解决方案
你可以用以下两种方案二选一,适配Blade循环渲染的场景:
方案1:绑定索引匹配对应内容(更直观)
Blade模板修改(循环部分)
在forEach循环时利用索引给每个内容块加唯一ID,点击时传入索引定位对应内容:
@foreach($lessons as $index => $item) <h2 class="lesson-h2" onclick="loadToggleAction({{ $index }})"> lesson {{ $index + 1 }} </h2> <a class="lesson-file" href="{{ "#play" }}"> <img class="show-lesson" src="img.png" title="مشاهده آنلاین این درس" height="24" onclick="loadToggleAction({{ $index }})"> </a> <div class="show" id="lesson-content-{{ $index }}"> {{ $item->content }} </div> @endforeach
JS代码修改
function loadToggleAction(index) { const content = document.getElementById(`lesson-content-${index}`); // 切换显隐 content.style.display = content.style.display === 'block' ? 'none' : 'block'; }
方案2:DOM节点定位(无需修改循环逻辑)
不用加索引,直接通过触发点击的元素的相对位置查找对应内容块,Blade代码只需要改事件传参:
HTML/Blade修改
把所有onclick="loadToggleAction()"改成onclick="loadToggleAction(event)"即可。
JS代码修改
function loadToggleAction(event) { const trigger = event.currentTarget; let contentEl; // 判断触发源是标题还是图标,查找对应的内容块 if (trigger.classList.contains('lesson-h2')) { // 标题后面是a标签,再后面是内容块 contentEl = trigger.nextElementSibling.nextElementSibling; } else if (trigger.classList.contains('show-lesson')) { // 图标父级是a标签,a标签后面是内容块 contentEl = trigger.parentElement.nextElementSibling; } if (!contentEl) return; // 切换显隐 contentEl.style.display = contentEl.style.display === 'block' ? 'none' : 'block'; }
内容的提问来源于stack exchange,提问作者user28212
相关产品推荐
相关产品推荐

