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

Bootstrap 5正式版多级下拉菜单旧菜单不关闭问题修复咨询

Bootstrap 5 正式版多级下拉菜单互斥关闭修复方案

问题根因

Bootstrap 5 正式版调整了下拉组件的事件触发逻辑,原有适配Beta版本的实现未区分内部子菜单切换和外部菜单点击场景,导致同级根下拉菜单无法互斥关闭,出现多个菜单同时展开的异常。

修复后完整实现代码

(function($bs) {
    const CLASS_NAME = 'has-child-dropdown-show';
    $bs.Dropdown.prototype.toggle = function(_orginal) {
        return function() {
            document.querySelectorAll('.' + CLASS_NAME).forEach(function(e) {
                e.classList.remove(CLASS_NAME);
            });
            let dd = this._element.closest('.dropdown').parentNode.closest('.dropdown');
            for (; dd && dd !== document; dd = dd.parentNode.closest('.dropdown')) {
                dd.classList.add(CLASS_NAME);
            }
            return _orginal.call(this);
        }
    }($bs.Dropdown.prototype.toggle);

    document.querySelectorAll('.dropdown').forEach(function(dd) {
        dd.addEventListener('hide.bs.dropdown', function(e) {
            if (this.classList.contains(CLASS_NAME)) {
                this.classList.remove(CLASS_NAME);
                e.preventDefault();
            }
            if(e.clickEvent) {
                const clickPath = e.clickEvent.composedPath();
                // 仅当点击当前下拉内部的切换按钮时才阻止关闭
                const isInnerToggle = clickPath.some(el => el.classList && el.classList.contains('dropdown-toggle') && this.contains(el));
                if(isInnerToggle) {
                    e.preventDefault();
                }
            }
            e.stopPropagation();
        });
    });

    //  hover效果,不需要可以删除以下代码
    function getDropdown(element) {
        return $bs.Dropdown.getInstance(element) || new $bs.Dropdown(element);
    }

    document.querySelectorAll('.dropdown-hover, .dropdown-hover-all .dropdown').forEach(function(dd) {
        dd.addEventListener('mouseenter', function(e) {
            let toggle = e.target.querySelector(':scope>[data-bs-toggle="dropdown"]');
            if (!toggle.classList.contains('show')) {
                getDropdown(toggle).toggle();
            }
        });
        dd.addEventListener('mouseleave', function(e) {
            let toggle = e.target.querySelector(':scope>[data-bs-toggle="dropdown"]');
            if (toggle.classList.contains('show')) {
                getDropdown(toggle).toggle();
            }
        });
    });
})(bootstrap);

使用说明

  • 保证HTML结构符合Bootstrap多级下拉嵌套规范,子下拉菜单需要嵌套在父级.dropdown节点内部
  • 代码需要在Bootstrap JS加载完成后执行
  • 不需要hover触发效果可直接删除hover相关的代码段,不影响点击功能

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.19 23:36:03