WordPress ACF重复器字段实现列表项展开折叠功能异常求助
解决ACF重复器折叠面板仅第一项生效的问题
这问题我太熟了!你遇到的核心问题是所有折叠面板都用了同一个ID myDIV——浏览器里document.getElementById()只会返回页面中第一个匹配的元素,所以不管点哪个列表项,操作的都是第一个面板。下面给你两种实用的解决方法:
方法一:给每个面板生成唯一ID(快速修改)
利用ACF自带的get_row_index()函数,给每个折叠面板生成独一无二的ID,再把这个ID传给点击函数:
修改后的PHP代码:
<?php if (have_rows('video_felt')): ?> <ul> <?php while (have_rows ('video_felt')): the_row(); //vars $afsnitOverskrift = get_sub_field('afsnit_titel'); ?> <li> <?php if($afsnitOverskrift): ?> <?php echo $afsnitOverskrift; ?> <?php endif;?> </li> <?php if (have_rows('video_liste')): ?> <ul> <?php while (have_rows ('video_liste')): the_row(); // 获取当前行的索引(ACF自带,从1开始) $rowIndex = get_row_index(); //vars $videListe = get_sub_field('video_navn'); $videoLinker = get_sub_field('vide_link');?> <!-- 把唯一ID传给点击函数 --> <li onclick="myFunction('myDIV-<?php echo $rowIndex; ?>')"> <?php if($videListe): ?> <a ><?php echo $videListe; ?></a> <!-- 生成唯一ID --> <div id="myDIV-<?php echo $rowIndex; ?>" style="display:none;"> <div class="youtube-player" data-id="<?php echo $videoLinker;?>"></div> </div> <?php endif;?> </li> <?php endwhile;?> </ul> <?php endif;?> <?php endwhile; ?> </ul> <?php endif;?>
修改后的JS代码:
// 接收目标ID参数 function myFunction(targetId) { var x = document.getElementById(targetId); if (x.style.display === "block") { x.style.display = "none"; } else { x.style.display = "block"; } }
方法二:用事件委托(更优雅,推荐)
内联onclick不利于代码维护,用事件委托可以让父元素监听所有子项的点击,通过DOM关系找到对应的折叠面板,完全不需要ID:
修改后的PHP代码:
<?php if (have_rows('video_felt')): ?> <ul> <?php while (have_rows ('video_felt')): the_row(); //vars $afsnitOverskrift = get_sub_field('afsnit_titel'); ?> <li> <?php if($afsnitOverskrift): ?> <?php echo $afsnitOverskrift; ?> <?php endif;?> </li> <?php if (have_rows('video_liste')): ?> <!-- 给父ul加个类方便选择 --> <ul class="video-list-container"> <?php while (have_rows ('video_liste')): the_row(); //vars $videListe = get_sub_field('video_navn'); $videoLinker = get_sub_field('vide_link');?> <!-- 给列表项加类,去掉内联onclick --> <li class="video-item"> <?php if($videListe): ?> <a ><?php echo $videListe; ?></a> <!-- 给面板加类 --> <div class="video-content" style="display:none;"> <div class="youtube-player" data-id="<?php echo $videoLinker;?>"></div> </div> <?php endif;?> </li> <?php endwhile;?> </ul> <?php endif;?> <?php endwhile; ?> </ul> <?php endif;?>
修改后的JS代码:
// 给父容器添加事件监听,委托给子项 document.querySelector('.video-list-container').addEventListener('click', function(e) { // 找到点击的.video-item元素(不管点在a标签还是li上都能匹配) const videoItem = e.target.closest('.video-item'); if (!videoItem) return; // 如果点击的不是video-item,直接退出 // 找到当前项对应的折叠面板 const content = videoItem.querySelector('.video-content'); // 切换显示状态 content.style.display = content.style.display === 'block' ? 'none' : 'block'; });
为什么第二种方法更好?
- 避免了ID重复的问题,代码更干净
- 不需要为每个元素绑定单独的事件,性能更优(尤其是列表项很多的时候)
- 后续新增动态加载的列表项也能自动生效,不用重新绑定事件
内容的提问来源于stack exchange,提问作者Jon Steinar Bjørgvinsson
相关产品推荐
相关产品推荐

