如何设置mat autocomplete按tab键不关闭以满足508无障碍标准?
问题原因
Mat Autocomplete 组件默认的键盘交互逻辑中,Tab 键被绑定了「关闭下拉面板、将焦点移动到下一个可聚焦元素」的默认行为,且原生设计仅将 mat-option 识别为面板内的合法可聚焦元素,你自定义在头部的 <a> 标签不属于默认的可聚焦序列,因此按下 Tab 时会直接触发面板关闭,无法聚焦到自定义链接。
解决步骤
1. 拦截 Tab 键的默认关闭行为
给 mat-autocomplete 绑定键盘事件,拦截 Tab/Shift+Tab 触发的默认关闭逻辑:
<mat-autocomplete #auto="matAutocomplete" (keydown.tab)="handleTabPress($event)" [autoActiveFirstOption]="false" >
在组件类中实现事件处理逻辑,手动控制焦点移动顺序,仅在焦点已经移动到面板内最后一个可聚焦元素后才允许关闭面板:
import { ViewChild, ElementRef } from '@angular/core'; import { MatAutocomplete } from '@angular/material/autocomplete'; // 组件类中 @ViewChild('auto') auto: MatAutocomplete; @ViewChild('searchBar') searchBar: ElementRef<HTMLInputElement>; // 拿自定义头部链接的引用 @ViewChild('recordLink') recordLink: ElementRef<HTMLAnchorElement>; handleTabPress(event: KeyboardEvent) { event.stopPropagation(); event.preventDefault(); const panelElements = [ this.searchBar.nativeElement, this.recordLink.nativeElement, ...this.auto.options.map(opt => opt._getHostElement()) ]; const currentIndex = panelElements.findIndex(el => el === document.activeElement); if (event.shiftKey) { // Shift+Tab 向前移动焦点 if (currentIndex === 0) { // 已经到输入框,关闭面板后走默认焦点跳转 this.auto.close(); event.preventDefault(); return; } panelElements[currentIndex - 1]?.focus(); } else { // Tab 向后移动焦点 if (currentIndex === panelElements.length - 1) { // 已经到最后一个选项,关闭面板后走默认焦点跳转 this.auto.close(); event.preventDefault(); return; } panelElements[currentIndex + 1]?.focus(); } }
2. 给自定义链接添加无障碍属性
给头部的 <a> 标签添加可聚焦标识和无障碍属性,确保屏幕阅读器可以正确识别:
<a #recordLink routerLink="/search-records" tabindex="0" aria-label="跳转到记录搜索页面" > Records </a>
3. 可选:优化自定义内容的识别
如果你的自定义内容较多,可以用 Angular Material 提供的 matAutocompleteContent 指令包裹全部自定义内容,让组件正确识别面板内的自定义节点:
<mat-autocomplete #auto="matAutocomplete"> <ng-template matAutocompleteContent> <!-- 你的自定义头部、选项等全部内容放在这里 --> <div class="bar"> <div>Search for:</div> <a #recordLink routerLink="/search-records">Records</a> </div> <div class="grid-title semi-bold gray--text">Top Results</div> <mat-option *ngFor="let option of filteredOptions | async" [value]="option.title" > {{ option.title }} </mat-option> </ng-template> </mat-autocomplete>
适配验证
完成修改后可做以下无障碍验证:
- 键盘操作:Tab/Shift+Tab 可以在输入框、自定义链接、选项之间正常移动焦点,不会误关面板
- 屏幕阅读器:可以正常朗读自定义链接的提示文本、选项内容
- 关闭逻辑:点击面板外、按下ESC键仍可以正常关闭下拉面板
内容的提问来源于stack exchange,提问作者Nathan Wichman
相关产品推荐
相关产品推荐

