Angular:关闭mat-menu并设置焦点到上一个/下一个元素的实现方法
问题代码
模板代码
<ng-container> <ng-container> <div class="class1" tabindex="0" [matMenuTriggerFor]="menu" #menuTrigger="matMenuTrigger"> <div class="customclass"> <i class="fa fa-bell-o"></i> <h2>Main Menu</h2> </div> </div> </ng-container> <mat-menu #menu="matMenu" class="myClass" > <div class="Custom"> <div mat-menu-item (click)="$event.stopPropagation()" (keydown)="myFunc($event)"> <div class="class2"> <h3>Label</h3> <div class="class3"> <p> some text, <a href="link address">first link</a>. Some Test text and link <a href="address" >second link</a> </p> </div> </div> </div> </mat-menu>
TS代码
let myLinks = this.elRef.nativeElement.getElementsByTagName('a'); for (let i = 0; i <= anchors.length-1; i++) { myLinks[i].setAttribute('tabindex', '0'); } myFunc(event: { stopPropagation: () => void }) { event.stopPropagation(); }
需求
- 在第一个链接按下
Shift+Tab时关闭菜单,同时将焦点设置到Main Menu; - 在最后一个链接按下
Tab时关闭菜单,同时将焦点设置到下一个元素。
实现步骤
1. 修正TS变量错误
原代码循环中误用了未定义的anchors变量,替换为myLinks:
const myLinks = this.elRef.nativeElement.getElementsByTagName('a'); for (let i = 0; i < myLinks.length; i++) { myLinks[i].setAttribute('tabindex', '0'); }
2. 获取菜单触发器实例
在组件类中通过@ViewChild拿到menuTrigger的引用,用于控制菜单开关:
import { Component, ViewChild, ElementRef } from '@angular/core'; import { MatMenuTrigger } from '@angular/material/menu'; @Component({ // 你的组件元数据(选择器、模板、样式等) }) export class YourComponent { @ViewChild('menuTrigger') private menuTrigger!: MatMenuTrigger; constructor(private elRef: ElementRef) {} // 其他组件逻辑... }
3. 完善键盘事件处理函数
修改myFunc,判断当前焦点链接的位置,处理Shift+Tab和Tab的场景:
myFunc(event: KeyboardEvent) { event.stopPropagation(); const myLinks = this.elRef.nativeElement.getElementsByTagName('a'); const currentLink = event.target as HTMLAnchorElement; // 第一个链接按Shift+Tab:关闭菜单,聚焦到Main Menu if (event.shiftKey && event.key === 'Tab' && currentLink === myLinks[0]) { this.menuTrigger.closeMenu(); const mainMenu = this.elRef.nativeElement.querySelector('.class1'); mainMenu?.focus(); event.preventDefault(); } // 最后一个链接按Tab:关闭菜单,聚焦到下一个可交互元素 if (!event.shiftKey && event.key === 'Tab' && currentLink === myLinks[myLinks.length - 1]) { this.menuTrigger.closeMenu(); event.preventDefault(); // 延迟确保菜单关闭后再切换焦点 setTimeout(() => { const focusableElements = Array.from( document.querySelectorAll('button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])') ); const currentIndex = focusableElements.indexOf(currentLink); if (currentIndex < focusableElements.length - 1) { focusableElements[currentIndex + 1]?.focus(); } }, 100); } }
内容的提问来源于stack exchange,提问作者Explorer
相关产品推荐
相关产品推荐

