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

侧边栏菜单异常展开bug排查及修复方案

侧边栏菜单多展开问题修复

问题描述

使用HTML、CSS、Bootstrap和JavaScript开发的侧边栏菜单,正常交互逻辑如下:

  • 点击「Student Management」时,展开其子菜单
  • 点击「Invoicing Management」时,自动折叠「Student Management」并展开自身子菜单

但存在异常场景:当所有菜单处于关闭状态时,快速多次点击「Student Management」,再点击一次「Invoicing Management」,最后切回点击「Student Management」,会出现两个菜单同时展开的情况。

当前代码

HTML代码

<!DOCTYPE html>
<html>
<head>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="description" content="">
    <meta name="author" content="">

    <title>SMS_Online</title>
    <link href="//maxcdn.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css" rel="stylesheet" id="bootstrap-css">
    <script src="//maxcdn.bootstrapcdn.com/bootstrap/4.1.1/js/bootstrap.min.js"></script>
    <script src="//cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
    <link href="//netdna.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css" rel="stylesheet" id="bootstrap-css">
    <script src="//netdna.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"></script>
    <script src="//code.jquery.com/jquery-1.11.1.min.js"></script>
    <link href="//maxcdn.bootstrapcdn.com/font-awesome/4.2.0/css/font-awesome.min.css" rel="stylesheet">
</head>
<body>
    <main role="main" class="container-fluid" style="padding:0px;">
        <div class="col-xs-03">
            <div class="sideMenu">
                <div class="menuItems">
                    <ul class="">
                        <li class="">
                            <a href="#">
                                <i class="fa fa-dashboard fa-lg"></i>Main Dashboard<span class="arrow"></span>
                            </a>
                        </li>
                        <li data-toggle="collapse" data-target="#studentsSubItems" class="collapsed">
                            <a href="#">
                                <i class="fas fa-user-graduate"></i>Student Management<i class="fas fa-chevron-down float-right sideMenuRightArrow"></i>
                            </a>
                            <ul class="sub-menu collapse" id="studentsSubItems">
                                <li>
                                    <a href="#">
                                        <i class="fas fa-chevron-right"></i>Student Main
                                    </a>
                                </li>
                                <li>
                                    <a href="#">
                                        <i class="fas fa-chevron-right"></i>Register Student
                                    </a>
                                </li>
                            </ul>
                        </li>
                        <li data-toggle="collapse" data-target="#invoicingSubItems" class="collapsed">
                            <a href="#">
                                <i class="fas fa-user-graduate"></i>Invoicing Management<i class="fas fa-chevron-down float-right sideMenuRightArrow"></i>
                            </a>
                            <ul class="sub-menu collapse" id="invoicingSubItems">
                                <li>
                                    <a href="#">
                                        <i class="fas fa-chevron-right"></i>Invoicing Main
                                    </a>
                                </li>
                                <li>
                                    <a href="#">
                                        <i class="fas fa-chevron-right"></i>Create an invoice
                                    </a>
                                </li>
                            </ul>
                        </li>
                    </ul>
                </div>
            </div>
        </div>
    </main>
</body>
</html>

CSS代码

.sideMenu {
    overflow: auto;
    font-family: verdana;
    font-size: 12px;
    font-weight: 200;
    background-color: #2e353d;
    width: 300px;
    height: 100vh;
    color: #e1ffff;
}

.sideMenu ul, #navbar ul,
.sideMenu li, #navbar li {
    list-style: none;
    padding: 0px;
    margin: 0px;
    cursor: pointer;
    color: #e1ffff;
}
.sideMenu ul,
.sideMenu li {
    line-height: 35px;
}

.sideMenuRightArrow {
    display: inline-block;
    padding-right: 10px;
    padding-top: 10px
}

.sideMenu ul .active,
.sideMenu li .active {
    border-left: 3px solid #d19b3d;
    background-color: #4f5b69;
}

.sideMenu ul .sub-menu li.active,
.sideMenu li .sub-menu li.active {
    color: #d19b3d;
}

.sideMenu ul .sub-menu li,
.sideMenu li .sub-menu li {
    background-color: #181c20;
    border: none;
    line-height: 28px;
    border-bottom: 1px solid #23282e;
    margin-left: 0px;
}

.sideMenu ul .sub-menu li:hover,
.sideMenu li .sub-menu li:hover {
    background-color: #020203;
}

.sideMenu li {
    padding-left: 0px;
    border-left: 3px solid #2e353d;
    border-bottom: 1px solid #23282e;
}

.sideMenu li a {
    text-decoration: none;
    color: #e1ffff;
}

.sideMenu li a i {
    padding-left: 10px;
    width: 20px;
    padding-right: 20px;
}

.sideMenu li:hover {
    border-left: 3px solid #d19b3d;
    background-color: #4f5b69;
    -webkit-transition: all 1s ease;
    -moz-transition: all 1s ease;
    -o-transition: all 1s ease;
    -ms-transition: all 1s ease;
    transition: all 1s ease;
}
@media (max-width: 768px) {
    #navbar {
        visibility: visible;
    }
    .sideMenu {
        visibility: hidden;
    }
}

@media (min-width: 769px) {
    #navbar {
        visibility: hidden;
    }
    .sideMenu {
        visibility: visible;
    }
}

JavaScript代码

$(document).ready(function () {
    $('.collapsed').on('click dblclick', function (ev) {
        if ($('.active').length > 0 &&
            !$(this).hasClass("active")) {
            $('.active').trigger("click");
            $('.active').removeClass("active");
        }
        $(this).addClass("active");
    });
    $('.sub-menu li').on('click dblclick', function (ev) {
        ev.stopPropagation();
    })
});

问题原因

快速点击会触发多次click和dblclick事件,事件队列堆积导致原代码中$('.active').trigger("click")的执行时机混乱;同时Bootstrap的collapse动画尚未完成时,菜单的active类和折叠状态就被修改,最终造成多个菜单同时处于展开状态。

修复方案

修复思路

  1. 移除dblclick事件监听,避免重复触发事件
  2. 手动控制菜单状态:点击当前菜单前,先关闭所有其他已展开的菜单
  3. 阻止Bootstrap默认折叠事件,避免自定义逻辑与框架默认逻辑冲突

修复后的JavaScript代码

$(document).ready(function () {
    $('.collapsed').on('click', function (ev) {
        ev.preventDefault();
        ev.stopPropagation();
        const $current = $(this);
        const targetId = $current.data('target');
        
        // 关闭所有其他展开的菜单
        $('.collapsed').not($current).each(function() {
            const $other = $(this);
            const otherTarget = $other.data('target');
            if (!$(otherTarget).hasClass('collapse')) {
                $(otherTarget).collapse('hide');
                $other.addClass('collapsed').removeClass('active');
            }
        });
        
        // 切换当前菜单的展开/折叠状态
        $(targetId).collapse('toggle');
        $current.toggleClass('active collapsed');
    });
    
    $('.sub-menu li').on('click', function (ev) {
        ev.stopPropagation();
    });
});

效果说明

修复后,无论如何快速点击菜单,同一时间只会有一个菜单处于展开状态,彻底解决了多菜单同时展开的异常问题。


内容的提问来源于stack exchange,提问作者Mohamed

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 01:35:20