如何设置父菜单与子菜单的active类?问题排查及改进需求
我来帮你搞定菜单active类的问题,咱们先梳理下当前代码的核心问题,再给出清晰的重构方案:
问题分析
你当前的代码有几个关键问题导致无法正确设置active类:
pages函数的匹配逻辑完全错误:$pagename == array($config['Pages'])是把整个Pages配置数组包裹成新数组,和字符串类型的$pagename做比较,永远不会匹配成功,所以一直输出no。- 没有区分父菜单和子菜单的激活规则:子菜单页面激活时,对应的父菜单也需要加上
active类。 - 函数返回的是
yes/no,而不是你需要的active类名,这就导致即使偶尔匹配成功,也会输出错误内容。
解决方案
我们可以重构整个菜单匹配逻辑,让它更清晰、更可靠:
1. 修正当前页面名称的获取逻辑
首先确保$pagename能正确获取到当前页面的路径名称,处理根路径等边界情况:
<?php $directoryURI = $_SERVER['REQUEST_URI']; $path = parse_url($directoryURI, PHP_URL_PATH); // 去掉路径首尾的斜杠,避免空元素 $components = explode('/', trim($path, '/')); // 如果是根路径(访问首页),默认设置为Dashboard $pagename = !empty($components[0]) ? $components[0] : 'Dashboard'; ?>
2. 重构菜单匹配函数
替换原来的pages函数,新增两个更明确的辅助函数,分别处理单页面匹配和父菜单匹配:
// 传入目标页面路径和当前页面,返回active类或空字符串 public function isActivePage($targetPage, $currentPage) { return $currentPage === $targetPage ? 'active' : ''; } // 传入父菜单下的所有子页面数组和当前页面,返回active类或空字符串 public function isParentMenuActive($childPages, $currentPage) { return in_array($currentPage, $childPages) ? 'active' : ''; }
3. 改造菜单代码
在菜单中分别调用这两个函数,为父菜单和子菜单设置正确的active类:
<div class="menu"> <ul class="list"> <li class="header">MAIN NAVIGATION</li> <!-- Home菜单:匹配Dashboard页面 --> <li class="<?php print $dash->isActivePage('Dashboard', $pagename); ?>"> <a href="/Dashboard"> <i class="material-icons">home</i> <span>Home</span> </a> </li> <!-- USD Market父菜单:匹配它的两个子页面 --> <li class="<?php print $dash->isParentMenuActive(['USD-Current-Trades', 'USD-Exchange-Trades'], $pagename); ?>"> <a href="javascript:void(0);" class="menu-toggle"> <i class="material-icons">trending_down</i> <span>USD ($) - Market Trades</span> </a> <ul class="ml-menu"> <!-- Current Trades子菜单:匹配USD-Current-Trades页面 --> <li class="<?php print $dash->isActivePage('USD-Current-Trades', $pagename); ?>"> <a href="/USD-Current-Trades"> <span>Current Trades</span> </a> </li> <!-- Exchange Trades子菜单:匹配USD-Exchange-Trades页面 --> <li class="<?php print $dash->isActivePage('USD-Exchange-Trades', $pagename); ?>"> <a href="/USD-Exchange-Trades"> <span>Exchange Trades</span> </a> </li> </ul> </li> </ul> </div>
4. (可选)基于JSON配置动态生成菜单
如果你的页面配置会经常变动,也可以直接基于JSON配置动态遍历生成菜单,避免硬编码:
<?php // 把你的JSON配置转成PHP数组 $pagesConfig = json_decode('{"Pages":{"Home":"Dashboard","USD Market":{"Current-Trades":"USD-Current-Trades","Exchange-Trades":"USD-Exchange-Trades"}}}', true)['Pages']; ?> <div class="menu"> <ul class="list"> <li class="header">MAIN NAVIGATION</li> <?php foreach ($pagesConfig as $menuName => $pageInfo): ?> <?php if (is_string($pageInfo)): ?> <!-- 一级菜单(没有子菜单) --> <li class="<?php print $dash->isActivePage($pageInfo, $pagename); ?>"> <a href="/<?php print $pageInfo; ?>"> <?php if ($menuName === 'Home'): ?> <i class="material-icons">home</i> <?php endif; ?> <span><?php print $menuName; ?></span> </a> </li> <?php else: ?> <!-- 带有子菜单的父菜单 --> <?php $childPagePaths = array_values($pageInfo); ?> <li class="<?php print $dash->isParentMenuActive($childPagePaths, $pagename); ?>"> <a href="javascript:void(0);" class="menu-toggle"> <?php if ($menuName === 'USD Market'): ?> <i class="material-icons">trending_down</i> <?php endif; ?> <span><?php print str_replace('Market', '($) - Market Trades', $menuName); ?></span> </a> <ul class="ml-menu"> <?php foreach ($pageInfo as $subMenuName => $subPagePath): ?> <li class="<?php print $dash->isActivePage($subPagePath, $pagename); ?>"> <a href="/<?php print $subPagePath; ?>"> <span><?php print str_replace('-', ' ', $subMenuName); ?></span> </a> </li> <?php endforeach; ?> </ul> </li> <?php endif; ?> <?php endforeach; ?> </ul> </div>
这样不管后续页面配置怎么变,只要修改JSON就能自动更新菜单,不用手动改HTML啦。
内容的提问来源于stack exchange,提问作者JamesBond
相关产品推荐
相关产品推荐

