CDK Focus Trap 在带有 Shift Tab 的对话框外单击时中断

CDK Focus Trap breaks on click outside dialog with Shift Tab

我有一个焦点陷阱,它会在 angular material 对话框打开时激活。父组件包含来自 a11yModule (https://material.angular.io/cdk/a11y/api#CdkTrapFocus) 的 cdkTrapFocus 指令,它的各个子组件可以有不同数量的输入。

焦点陷阱在对话框打开时按预期工作,防止用户按 Tab 键或 Shift-Tab 键访问对话框后面的项目。但是,当用户单击对话框后面的灰色区域,然后按 shift-tab 键时,他们可以访问对话框后面的所有项目。

在他们按下 shift-tab(或 tab)足够多次以将焦点移回对话框内之前,焦点陷阱一直被打破。正确的行为是焦点只会停留在对话框中,无论在对话框内部或外部单击什么。

在大多数情况下,我已经检查了上面的 link 以查看有哪些选项可以确保焦点仍然被困住,但是很难确定哪些指令对这个问题最有用。下面是父组件html模板。

<div class="dialog-frame dialog-fade dialog-backgray" [ngClass]="{ 'in': shown }" role="dialog">
    <div class="dialog-main" [style.width]="dialogWidth" id="dialog-main" cdkTrapFocus>          
       <ng-template #element> </ng-template>
    </div>
</div>

如果阅读本文的任何人对此有解决方案,我将不胜感激。

我运行进入shift-tab问题。我的解决方案是添加一个 keydown 侦听器,如果事件路径不在模态中,它会阻止焦点:

@HostListener('document:keydown', ['$event'])
onTab(event) {
  if (event.key == 'Tab' && this.modalIsOpen) {
    let path = event.composedPath();
    let modal = path.find((element) => element.tagName && element.tagName.toLowerCase() == this.modalComponentTagName);
    if (path && !modal) {
      // Tabbing outside of the modal.
      event.preventDefault();
      this.focusOnFirstElementInModal();
    }
  }
}

对我来说 this.modalIsOpenthis.document.body.classList.contains('modal-open')this.modalComponentTagName'app-donate-modal'this.focusOnFirstElementInModal() 关注模式的关闭按钮。