WordPress父菜单项点击仅显示对应子导航问题求助
实现WordPress父菜单项点击显示对应子项的解决方案
我来帮你搞定这个点击父菜单项显示对应子项的需求,分后端数据整理和前端交互实现两部分来做,逻辑清晰又好维护:
后端:优化菜单数据结构,关联父子项
你原来的函数只是返回所有菜单项,没有区分父子关系,我们先把数据整理成「父项包含子项数组」的结构,这样前端渲染时能直接拿到对应关系:
function cr_get_menu_items($menu_location) { $locations = get_nav_menu_locations(); // 增加容错:先判断菜单位置是否存在,避免报错 if (!isset($locations[$menu_location])) { return []; } $menu = get_term($locations[$menu_location], 'nav_menu'); $items = wp_get_nav_menu_items($menu->term_id); // 初始化父项和子项容器 $menu_tree = []; $children = []; foreach ($items as $item) { // parent为0的是顶级父菜单项 if ($item->menu_item_parent == 0) { $menu_tree[$item->ID] = $item; // 给父项添加children属性,默认空数组 $menu_tree[$item->ID]->children = []; } else { // 子项按父项ID分组 $children[$item->menu_item_parent][] = $item; } } // 把分组后的子项挂载到对应父项上 foreach ($menu_tree as &$parent) { if (isset($children[$parent->ID])) { $parent->children = $children[$parent->ID]; } } // 转成索引数组,方便前端循环 return array_values($menu_tree); }
前端:渲染模板+点击交互实现
现在模板里可以直接拿到带children属性的父项,我们把对应子菜单放在父项容器里,默认隐藏,再用JS实现点击切换显示:
1. 导航模板代码
<?php $nav = cr_get_menu_items('navigation_menu') ?> <nav class="main-navigation"> <?php foreach ($nav as $parent_item) : ?> <div class="nav-parent-item"> <a href="<?php echo esc_url($parent_item->url) ?>" class="parent-link"> <?php echo esc_html($parent_item->title) ?> <!-- 有子项时显示下拉图标 --> <?php if (!empty($parent_item->children)) : ?> <span class="dropdown-arrow">▼</span> <?php endif; ?> </a> <!-- 子菜单容器,默认隐藏 --> <?php if (!empty($parent_item->children)) : ?> <ul class="nav-submenu" style="display: none;"> <?php foreach ($parent_item->children as $child_item) : ?> <li class="submenu-item"> <a href="<?php echo esc_url($child_item->url) ?>"> <?php echo esc_html($child_item->title) ?> </a> </li> <?php endforeach; ?> </ul> <?php endif; ?> </div> <?php endforeach; ?> </nav>
2. 点击交互JS(原生JS,兼容性好)
document.addEventListener('DOMContentLoaded', function() { // 获取所有父菜单项的链接 const parentLinks = document.querySelectorAll('.nav-parent-item .parent-link'); parentLinks.forEach(link => { link.addEventListener('click', function(e) { const subMenu = this.nextElementSibling; // 只有当前父项有子菜单时才触发交互 if (subMenu && subMenu.classList.contains('nav-submenu')) { // 可选:阻止父链接默认跳转(如果希望点击只展开不跳转) e.preventDefault(); // 切换子菜单显示状态 subMenu.style.display = subMenu.style.display === 'none' ? 'block' : 'none'; // 可选:关闭其他已打开的子菜单(实现单选展开) document.querySelectorAll('.nav-submenu').forEach(otherMenu => { if (otherMenu !== subMenu) { otherMenu.style.display = 'none'; } }); } }); }); });
3. 可选:添加基础样式美化
.main-navigation { display: flex; gap: 2rem; background-color: #f8f9fa; padding: 1rem 2rem; } .nav-parent-item { position: relative; } .parent-link { text-decoration: none; color: #333; display: flex; align-items: center; gap: 0.3rem; } .dropdown-arrow { font-size: 0.8rem; } .nav-submenu { position: absolute; top: 100%; left: 0; background-color: white; border: 1px solid #eee; border-radius: 4px; list-style: none; padding: 0.8rem 0; margin: 0; min-width: 150px; } .submenu-item a { display: block; padding: 0.5rem 1rem; text-decoration: none; color: #333; } .submenu-item a:hover { background-color: #f8f9fa; }
补充说明
- 如果希望点击父链接正常跳转,同时点击下拉图标展开子菜单,可以把点击事件绑定到
.dropdown-arrow元素上,而不是整个父链接。 - 若需要更流畅的动画效果,可以把
display切换改成opacity+height的CSS过渡动画。
内容的提问来源于stack exchange,提问作者Liz
相关产品推荐
相关产品推荐

