CodeIgniter后台面板侧边栏菜单Active类错误添加问题解决
Hey there, let's break down why this is happening and fix it right away!
The Root Cause
Your current JavaScript uses indexOf() to match the current path segment against link hrefs. When you're on the dashboard (/admin), the current variable ends up being admin. Since all your sub-page links (like admin/settings or admin/activityLog) contain the string admin, they all get flagged as "active" by the indexOf() check—this is the bug.
Solution 1: Fix the JavaScript with Exact Path Matching
Instead of checking if the link contains the current segment, we'll do an exact match of the full path. Here's the revised JS code:
// Get the full current path (without domain) const currentPath = location.pathname; // Ensure path starts with a slash to avoid mismatches const normalizedCurrentPath = currentPath.startsWith('/') ? currentPath : `/${currentPath}`; $('#sidebar .nav li a').each(function() { const $link = $(this); // Resolve the link's href to an absolute path (handles relative links correctly) const linkPath = new URL($link.attr('href'), window.location.origin).pathname; // Only add active classes if paths match exactly if (linkPath === normalizedCurrentPath) { // Mark the parent nav-item as active $link.parents('.nav-item').last().addClass('active'); // Handle sub-menu expansion if needed if ($link.parents('.sub-menu').length) { $link.closest('.collapse').addClass('show'); $link.addClass('active'); } } });
What this does:
- Grabs the full current path (e.g.,
/adminor/admin/settings) - Uses the
URLAPI to convert relative links to absolute paths, so we're comparing apples to apples - Uses strict equality (
===) to ensure only the exact matching link gets the active class
Solution 2: PHP-side Active Class (Recommended)
Since you're using CodeIgniter, we can leverage the framework's URI helper to dynamically add active classes server-side—this is more reliable because it doesn't depend on JS, and works even if JS is disabled.
Update your sidebar.php code like this:
<nav class="sidebar sidebar-offcanvas" id="sidebar"> <ul class="nav"> <!-- Dashboard Item --> <li class="nav-item <?php echo ($this->uri->segment(1) === 'admin' && $this->uri->segment(2) === NULL) ? 'active' : ''; ?>"> <?php echo anchor( 'admin', '<span class="menu-title"><i class="mdi mdi-home menu-icon"></i> Dashboard</span>', 'class="nav-link"' ); ?> </li> <!-- Settings Parent Item --> <li class="nav-item <?php echo (in_array($this->uri->segment(2), ['settings', 'activityLog'])) ? 'active' : ''; ?>"> <a class="nav-link <?php echo (in_array($this->uri->segment(2), ['settings', 'activityLog'])) ? '' : 'collapsed'; ?>" data-toggle="collapse" href="#settings" aria-expanded="<?php echo (in_array($this->uri->segment(2), ['settings', 'activityLog'])) ? 'true' : 'false'; ?>" aria-controls="settings" > <span class="menu-title"> <i class="mdi mdi-settings menu-icon"></i> Settings </span> <i class="menu-arrow"></i> </a> <!-- Settings Sub-Menu --> <div class="collapse <?php echo (in_array($this->uri->segment(2), ['settings', 'activityLog'])) ? 'show' : ''; ?>" id="settings"> <ul class="nav flex-column sub-menu"> <li class="nav-item <?php echo ($this->uri->segment(2) === 'settings') ? 'active' : ''; ?>"> <?php echo anchor( 'admin/settings', 'Settings', 'class="nav-link ' . (($this->uri->segment(2) === 'settings') ? 'active' : '') . '"' ); ?> </li> <li class="nav-item <?php echo ($this->uri->segment(2) === 'activityLog') ? 'active' : ''; ?>"> <?php echo anchor( 'admin/activityLog', 'Activity Log', 'class="nav-link ' . (($this->uri->segment(2) === 'activityLog') ? 'active' : '') . '"' ); ?> </li> </ul> </div> </li> </ul> </nav>
How this works:
$this->uri->segment(n)grabs the nth part of the URL (e.g.,segment(1)isadmin,segment(2)issettingsfor/admin/settings)- We check if the current segment matches the link's target, and dynamically add
activeorshowclasses where needed - The parent settings item stays active when any of its sub-links are active, and the sub-menu stays expanded
Final Notes
The PHP solution is my go-to here because it's more robust—no JS dependency, and the correct active state is rendered immediately when the page loads. If you prefer to stick with JS, the exact path matching will fix the original issue.
内容的提问来源于stack exchange,提问作者WP Dev

