Laravel中JS Readmore仅对首个数据库对象生效,如何适配全部对象?
问题原因
循环生成内容时重复使用了相同的ID(dots、moretext、myBtn),但DOM中ID必须唯一,document.getElementById只会匹配第一个元素,导致后续按钮无法找到对应条目进行操作。
修复方案
改用类选择器替代ID,结合元素相对查找,让每个按钮只操作自身所属条目的内容:
修改后的HTML
<div class="container row"> @forelse ($counters as $key => $counter) <!-- 每个条目单独包裹容器,方便后续查找 --> <div class="counter-item"> <div> <h6>Title</h6> <p>{{ $counter->title }}</p> </div> <div> <h6>Address</h6> <p>{{ $counter->address }}</p> </div> <span class="dots">...</span> <span class="moretext"> <div> <h6>Email</h6> <p>{{ $counter->email }}</p> </div> <div> <h6>Contact no.</h6> <p>{{ $counter->contact }}</p> </div> </span> <!-- 传递当前按钮到函数,明确操作目标 --> <button onclick="toggleReadMore(this)" class="read-more-btn">Read more</button> </div> @empty No information published yet. @endforelse </div>
修改后的CSS
<style> /* 用类选择器替代ID,适配所有条目 */ .moretext { display: none; } .dots { display: inline; } </style>
修改后的JS
<script> function toggleReadMore(btn) { // 获取当前按钮所属的条目容器 const item = btn.closest('.counter-item'); // 在当前条目内查找对应的元素 const dots = item.querySelector('.dots'); const moreText = item.querySelector('.moretext'); // 处理初始状态(CSS设置的display不会体现在style属性中) if (moreText.style.display === "none" || moreText.style.display === "") { dots.style.display = "none"; btn.textContent = "Read less"; moreText.style.display = "inline"; } else { dots.style.display = "inline"; btn.textContent = "Read more"; moreText.style.display = "none"; } } </script>
核心修改点
- 用类替代重复ID,遵循DOM唯一性规则
- 给每个条目添加容器,通过按钮的
closest方法锁定操作范围 - 函数接收按钮自身作为参数,确保操作对应条目的内容
- 兼容初始CSS设置的隐藏状态
内容的提问来源于stack exchange,提问作者Obi Kolin
相关产品推荐
相关产品推荐

