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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 08:12:36