如何在悬停时打开和关闭Angular mat菜单
这个问题是参考
this Github问题,mat-menu无法使用鼠标悬停切换,我基本上试图用角度材料的菜单替换基于bootstrap的水平导航菜单.阻止我复制基于bootstrap的菜单的唯一一件事就是在悬停时打开和关闭mat-menu.
正如上面的Github问题所提到的,有一些解决方法可以实现我想要的,例如使用,mouseEnter (mouseenter)="menuTrigger.openMenu()" 或在Mat菜单中添加span以便将mat-menu绑定, <mat-menu #menu="matMenu" overlapTrigger="false"> <span (mouseleave)="menuTrigger.closeMenu()"> <button mat-menu-item>Item 1</button> <button mat-menu-item>Item 2</button> </span> </mat-menu> 但是没有一个解决方案似乎涵盖了每一个小场景, 例如 如上面的Github问题所述,第一个SO解决方案存在以下问题.
并且在尝试解决上述问题之一但不能正常工作的跨度解决方案中,例如, 将鼠标悬停在MatMenuTrigger上可以按预期打开mat菜单,但是如果用户在没有输入mat-menu的情况下移动鼠标,则它不会自动关闭,这是错误的. 同时移动到其中一个级别的两个子菜单也关闭了一级菜单,这不是我想要的, P.S将鼠标从一个打开的菜单移动到下一个兄弟菜单不会打开下一个菜单.我想这可能很难实现,如here所述,但我认为其中一些可能是可以实现的吗? 这是一个基本的stackBlitz,它重现了我正在经历的,任何帮助表示赞赏. 解决方法
第一个挑战是当由于叠加的z索引而生成CDK叠加时,mat-menu从按钮中窃取焦点…为了解决这个问题,您需要在按钮的样式中设置z-index. ..
>当您向按钮添加(mouseleave)时,这将停止递归循环.风格= “的z-index:1050” 接下来,您需要跟踪levelone和levelTwo菜单的所有进入和离开事件的状态,并将该状态存储在两个组件变量中. enteredButton = false; isMatMenuOpen = false; isMatMenu2Open = false; 接下来为两个菜单级别创建菜单enter和menuLeave方法.通知menuLeave(触发器)检查是否访问了level2,如果为true则不执行任何操作. 请注意:menu2Leave()具有逻辑,允许导航回到第一级但是如果退出另一侧则关闭两者…也可以在离开关卡时移除按钮焦点. menuenter() { this.isMatMenuOpen = true; if (this.isMatMenu2Open) { this.isMatMenu2Open = false; } } menuLeave(trigger,button) { setTimeout(() => { if (!this.isMatMenu2Open && !this.enteredButton) { this.isMatMenuOpen = false; trigger.closeMenu(); this.ren.removeClass(button['_elementRef'].nativeElement,'cdk-focused'); this.ren.removeClass(button['_elementRef'].nativeElement,'cdk-program-focused'); } else { this.isMatMenuOpen = false; } },80) } menu2enter() { this.isMatMenu2Open = true; } menu2Leave(trigger1,trigger2,button) { setTimeout(() => { if (this.isMatMenu2Open) { trigger1.closeMenu(); this.isMatMenuOpen = false; this.isMatMenu2Open = false; this.enteredButton = false; this.ren.removeClass(button['_elementRef'].nativeElement,'cdk-program-focused'); } else { this.isMatMenu2Open = false; trigger2.closeMenu(); } },100) } buttonEnter(trigger) { setTimeout(() => { if(this.prevButtonTrigger && this.prevButtonTrigger != trigger){ this.prevButtonTrigger.closeMenu(); this.prevButtonTrigger = trigger; trigger.openMenu(); } else if (!this.isMatMenuOpen) { this.enteredButton = true; this.prevButtonTrigger = trigger trigger.openMenu() } else { this.enteredButton = true; this.prevButtonTrigger = trigger } }) } buttonLeave(trigger,button) { setTimeout(() => { if (this.enteredButton && !this.isMatMenuOpen) { trigger.closeMenu(); this.ren.removeClass(button['_elementRef'].nativeElement,'cdk-program-focused'); } if (!this.isMatMenuOpen) { trigger.closeMenu(); this.ren.removeClass(button['_elementRef'].nativeElement,'cdk-program-focused'); } else { this.enteredButton = false; } },100) } HTML 下面是如何连接所有. <ng-container *ngFor="let menuItem of modulesList"> <ng-container *ngIf="!menuItem.children"> <a class="nav-link"> <span class="icon fa" [ngClass]="menuItem.icon"></span> <span class="text-holder">{{menuItem.label}}</span> </a> </ng-container> <ng-container *ngIf="menuItem.children.length > 0"> <button #button mat-button [matMenuTriggerFor]="levelOne" #levelOneTrigger="matMenuTrigger" (mouseenter)="levelOneTrigger.openMenu()" (mouseleave)="buttonLeave(levelOneTrigger,button)" style="z-index:1050"> <span class="icon fa" [ngClass]="menuItem.icon"></span> <span>{{menuItem.label}} <i class="fa fa-chevron-down"></i> </span> </button> <mat-menu #levelOne="matMenu" direction="down" yPosition="below"> <span (mouseenter)="menuenter()" (mouseleave)="menuLeave(levelOneTrigger,button)"> <ng-container *ngFor="let childL1 of menuItem.children"> <li class="p-0" *ngIf="!childL1.children" mat-menu-item> <a class="nav-link">{{childL1.label}} <i *ngIf="childL1.icon" [ngClass]="childL1.icon"></i> </a> </li> <ng-container *ngIf="childL1.children && childL1.children.length > 0"> <li mat-menu-item #levelTwoTrigger="matMenuTrigger" [matMenuTriggerFor]="levelTwo"> <span class="icon fa" [ngClass]="childL1.icon"></span> <span>{{childL1.label}}</span> </li> <mat-menu #levelTwo="matMenu"> <span (mouseenter)="menu2enter()" (mouseleave)="menu2Leave(levelOneTrigger,levelTwoTrigger,button)"> <ng-container *ngFor="let childL2 of childL1.children"> <li class="p-0" mat-menu-item> <a class="nav-link">{{childL2.label}} <i *ngIf="childL2.icon" [ngClass]="childL2.icon"></i> </a> </li> </ng-container> </span> </mat-menu> </ng-container> </ng-container> </span> </mat-menu> </ng-container> </ng-container> Stackblitz https://stackblitz.com/edit/mat-nested-menu-yclrmd?embed=1&file=app/nested-menu-example.html (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |