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

表格中多Bootstrap下拉菜单切换异常:DOM残留及全关问题求助

解决Bootstrap表格中下拉菜单切换异常的问题

问题场景

在<table>中使用Bootstrap下拉菜单时,原本存在菜单被截断、显示异常的问题。将下拉菜单移出表格容器到<body>后,单个下拉菜单点击外部关闭可正常工作,但如果打开一个下拉菜单后立即点击另一行的下拉菜单,会出现所有下拉菜单关闭,且之前打开的菜单DOM残留于<body>中的异常情况。

原HTML代码:

<table>
    @foreach(...){<tr>
        <td>
            <div class="dropdown">
               <button data-bs-toggle="dropdown" data-bs-auto-close="true" data-bs-offset="0,2" aria-expanded="false">See review</button>
               <div class="dropdown-menu" role="menu">/*some menu items*/</div>
            </div>
        </td>
    </tr> 
  }
</table>

原JS代码:

var dropdownMenu:any;   
    $('.dropdown').on('show.bs.dropdown', function (e:any) {        
        dropdownMenu = $(this).find('.dropdown-menu');
        $('body').append(dropdownMenu.detach());
        dropdownMenu.css('display', 'block');
        dropdownMenu.position({
            'my': 'right top',
            'at': 'right bottom',
            'of': $(e.relatedTarget)
        });     
    });

    $(".dropdown").on('hide.bs.dropdown', function (e: any) {
        if (dropdownMenu != undefined) {
            $(e.currentTarget).append(dropdownMenu.detach());
            dropdownMenu.hide();
        }
    });

问题原因

  1. 使用全局变量dropdownMenu存储当前菜单,切换下拉菜单时,新菜单会覆盖全局变量,导致旧菜单的hide.bs.dropdown事件触发时,无法找到对应的DOM元素,从而残留于<body>中。
  2. Bootstrap的data-bs-auto-close="true"会在点击其他下拉按钮时触发所有已打开菜单的隐藏事件,但此时全局变量已指向新菜单,旧菜单无法被正确放回原容器。

修复方案

移除全局变量,改用每个下拉容器的data()方法存储对应菜单;在显示新菜单前主动关闭所有已打开菜单,确保状态一致。

修改后的JS代码:

// 绑定下拉菜单显示事件
$('.dropdown').on('show.bs.dropdown', function (e) {
    // 先关闭所有已处于打开状态的下拉菜单
    $('.dropdown.show').dropdown('hide');
    
    const $currentDropdown = $(this);
    const $menu = $currentDropdown.find('.dropdown-menu');
    
    // 将当前菜单存入下拉容器的data中,避免全局变量冲突
    $currentDropdown.data('attachedMenu', $menu);
    
    // 将菜单移到body并设置显示与定位
    $('body').append($menu.detach());
    $menu.css('display', 'block');
    $menu.position({
        'my': 'right top',
        'at': 'right bottom',
        'of': $(e.relatedTarget)
    });
});

// 绑定下拉菜单隐藏事件
$(".dropdown").on('hide.bs.dropdown', function () {
    const $currentDropdown = $(this);
    // 从当前下拉容器的data中取出对应的菜单
    const $menu = $currentDropdown.data('attachedMenu');
    
    if ($menu) {
        // 将菜单放回原下拉容器并隐藏
        $currentDropdown.append($menu.detach());
        $menu.hide();
        // 清除data中的存储,避免残留
        $currentDropdown.removeData('attachedMenu');
    }
});

关键修改点

  • 去掉全局变量,用每个.dropdown元素的data()存储专属菜单DOM,避免切换时的变量覆盖问题。
  • 显示新菜单前主动关闭所有已打开的下拉菜单,触发对应的hide事件,让旧菜单能正确回到原容器。
  • 在hide事件中从当前下拉容器的data中取菜单,确保操作的是当前容器对应的菜单,不会混淆。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 01:45:42