如何让Blazor网站中Bootstrap 5.3.x下拉菜单正常工作
Blazor Server中Bootstrap 5.3.x下拉菜单失效问题解决
问题现象
在Blazor Server项目中使用Bootstrap 5.3.x官方下拉菜单示例,点击按钮无任何反应。已在_Host.cshtml中按规范引入Bootstrap CSS(放置于<head>标签内)和JS(放置于</body>前),但官方示例代码无法触发下拉展开。
临时修改方案:给下拉切换按钮和菜单容器添加ID,将data-bs-toggle="dropdown"替换为data-bs-toggle="collapse",并设置data-bs-target指向菜单ID(需添加#前缀),才能实现菜单展开收起,但官方提供的4种自动关闭逻辑完全失效。
无法正常工作的官方示例代码
<div class="dropdown"> <button class="btn btn-secondary dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-expanded="false"> Dropdown button </button> <ul class="dropdown-menu"> <li><a class="dropdown-item" href="#">Action</a></li> <li><a class="dropdown-item" href="#">Another action</a></li> <li><a class="dropdown-item" href="#">Something else here</a></li> </ul> </div>
修改后可工作的代码(仅实现基础展开,无自动关闭)
<div class="dropdown"> <button class="btn btn-secondary dropdown-toggle" type="button" data-bs-toggle="collapse" aria-expanded="false" id="thing1" data-bs-target="#thing2"> Dropdown button </button> <ul class="dropdown-menu collapse" id="thing2" aria-labelledby="thing1"> <li><a class="dropdown-item" href="#">Action</a></li> <li><a class="dropdown-item" href="#">Another action</a></li> <li><a class="dropdown-item" href="#">Something else here</a></li> </ul> </div>
问题根源
- JS加载顺序错误:Bootstrap 5的下拉菜单依赖Popper.js,但你的
_Host.cshtml中Bootstrap JS先于Popper.js加载,导致Bootstrap无法初始化Popper相关功能,下拉触发器失效。 - Blazor Server DOM事件拦截:Blazor Server的事件冒泡机制会拦截原生JS事件,导致Bootstrap无法正确捕捉下拉按钮的点击事件,即使加载顺序正确也可能失效。
解决方案
1. 修正JS加载顺序
将Popper.js放在Bootstrap JS之前加载,确保Bootstrap能正确依赖Popper:
<!-- 先加载Popper.js --> <script type="text/javascript" src="~/js/popper/popper.min.js"></script> <!-- 再加载Bootstrap JS --> <script type="text/javascript" src="~/js/bootstrap/bootstrap.min.js"></script>
2. 手动初始化Bootstrap下拉组件
由于Blazor Server的DOM更新特性,Bootstrap组件可能无法自动初始化,需在组件渲染完成后手动触发:
在Blazor组件中添加代码:
@inject IJSRuntime JSRuntime @code { protected override async Task OnAfterRenderAsync(bool firstRender) { if (firstRender) { await JSRuntime.InvokeVoidAsync("initBootstrapDropdowns"); } } }
在_Host.cshtml的</body>前添加全局初始化函数:
<script> function initBootstrapDropdowns() { document.querySelectorAll('[data-bs-toggle="dropdown"]').forEach(element => { new bootstrap.Dropdown(element); }); } </script>
3. 恢复自动关闭功能
完成上述两步后,即可使用官方的data-bs-auto-close属性实现自动关闭逻辑,示例如下:
<div class="dropdown"> <button class="btn btn-secondary dropdown-toggle" type="button" data-bs-toggle="dropdown" data-bs-auto-close="outside" aria-expanded="false"> 点击外部关闭下拉菜单 </button> <ul class="dropdown-menu"> <li><a class="dropdown-item" href="#">Action</a></li> <li><a class="dropdown-item" href="#">Another action</a></li> </ul> </div>
可选方案:使用Blazor Bootstrap组件库
如果原生Bootstrap与Blazor的集成仍有问题,可直接使用官方维护的Blazor Bootstrap组件库,封装好的组件会自动处理JS与Blazor的交互,无需手动初始化。
内容的提问来源于stack exchange,提问作者PKD
相关产品推荐
相关产品推荐

