如何用JavaScript关闭MudBlazor NavMenu已开下拉?原生实现咨询
MudBlazor导航菜单:实现下拉菜单互斥展开(纯JS/HTML+原生组件方案)
一、纯JavaScript + HTML实现方案
你之前的JS代码操作mud-expand-icon类无法正确控制展开状态,因为MudBlazor的MudNavGroup展开状态由内部属性管理,对应的DOM标识类是mud-nav-group-expanded。以下是修正后的实现:
document.addEventListener('DOMContentLoaded', function () { // 获取所有导航组的展开按钮 const expandButtons = document.querySelectorAll('.mud-nav-group > .mud-nav-link > .mud-expand-icon'); expandButtons.forEach(button => { button.addEventListener('click', function (e) { // 阻止事件冒泡,避免触发父元素重复操作 e.stopPropagation(); const currentGroup = this.closest('.mud-nav-group'); // 遍历所有展开按钮,关闭当前组之外的已展开组 expandButtons.forEach(btn => { const group = btn.closest('.mud-nav-group'); if (group !== currentGroup && group.classList.contains('mud-nav-group-expanded')) { // 模拟点击展开按钮,同步组件内部状态 btn.click(); } }); }); }); });
关键说明
- 直接操作展开按钮的点击事件,和用户手动操作行为一致,确保组件状态与DOM同步
- 通过
mud-nav-group-expanded类判断组是否处于展开状态,这是MudBlazor原生的状态标识 - 阻止事件冒泡避免触发
MudNavGroup本身的点击事件导致逻辑冲突
二、MudBlazor原生组件实现方案(推荐)
纯JS方案依赖DOM结构,易受组件版本更新影响,推荐用Blazor状态绑定实现,更稳定可靠:
<MudNavMenu> <MudText Typo="Typo.subtitle2" Color="Color.Inherit" Class="ml-4 my-3"></MudText> @foreach (var item in BuildNavMenu()) { if (item.Children.Any()) { <MudNavGroup Title="@item.Title" IconColor="@item.IconColor" Icon="@item.Icon" HideExpandIcon="false" Id="navGroup_@item.Title.Replace(" ", "_")" Expanded="@(CurrentExpandedGroup == item.Title)" OnExpandedChanged="(expanded) => HandleGroupExpanded(expanded, item.Title)"> @foreach (var child in item.Children) { <MudNavLink Href="@child.Href" IconColor="@child.IconColor" Icon="@child.Icon">@child.Title</MudNavLink> } </MudNavGroup> } else { <MudNavLink Href="@item.Href" IconColor="@item.IconColor" Icon="@item.Icon">@item.Title</MudNavLink> } } </MudNavMenu> @code { public class NavItem { public string Title { get; set; } public string Href { get; set; } public string Icon { get; set; } public Color IconColor { get; set; } public List<NavItem> Children { get; set; } = new List<NavItem>(); } private string CurrentExpandedGroup { get; set; } private List<NavItem> BuildNavMenu() { return new List<NavItem> { new NavItem { Title = "Home", Href = "/", Icon = Icons.Material.TwoTone.Home, IconColor = Color.Inherit }, new NavItem { Title = "Reports", Icon = Icons.Material.TwoTone.Description, IconColor = Color.Secondary, Children = new List<NavItem> { new NavItem { Title = "Sales", Href = "/reports/sales", Icon = Icons.Material.TwoTone.TrendingUp, IconColor = Color.Secondary }, new NavItem { Title = "Expenses", Href = "/reports/expenses", Icon = Icons.Material.TwoTone.MoneyOff, IconColor = Color.Secondary } } }, new NavItem { Title = "Settings", Icon = Icons.Material.TwoTone.Settings, IconColor = Color.Info, Children = new List<NavItem> { new NavItem { Title = "Profile", Href = "/settings/profile", Icon = Icons.Material.TwoTone.Person, IconColor = Color.Info }, new NavItem { Title = "Security", Href = "/settings/security", Icon = Icons.Material.TwoTone.Security, IconColor = Color.Info } } } }; } private void HandleGroupExpanded(bool expanded, string groupTitle) { if (expanded) { // 展开当前组,关闭其他所有组 CurrentExpandedGroup = groupTitle; } else { // 折叠当前组时,清空记录 if (CurrentExpandedGroup == groupTitle) { CurrentExpandedGroup = null; } } } }
关键说明
- 通过
CurrentExpandedGroup变量维护当前展开的组标识,实现互斥逻辑 - 利用
Expanded绑定和OnExpandedChanged事件同步组件状态,完全符合MudBlazor的组件设计逻辑 - 代码集中在C#层,无需依赖DOM结构,组件更新后依然稳定运行
内容的提问来源于stack exchange,提问作者Rohit Suryaa Saravanan
相关产品推荐
相关产品推荐

