CDK Focus Trap прерывается при щелчке вне диалогового окна с помощью Shift Tab

У меня есть ловушка фокуса, которая активируется при открытии диалогового окна углового материала. Родительский компонент содержит директиву cdkTrapFocus из модуля a11yModule (https://material.angular.io/cdk/a11y/api#CdkTrapFocus), и его различные дочерние элементы могут иметь различное количество входных данных.

Ловушка фокуса работает должным образом, когда диалоговое окно открыто, не позволяя пользователю нажимать вкладку или Shift-Tab для доступа к элементам за диалоговым окном. Однако, когда пользователь щелкает затененную область позади диалогового окна, а затем нажимает Shift-Tab, он получает доступ ко всем элементам позади диалогового окна.

Ловушка фокуса остается сломанной до тех пор, пока они не нажмут Shift-Tab (или Tab) достаточное количество раз, чтобы переместить фокус обратно в диалоговое окно. Правильным поведением было бы то, что фокус всегда остается в диалоговом окне, независимо от того, что щелкнули внутри или за пределами диалогового окна.

По большей части я просмотрел приведенную выше ссылку, чтобы увидеть, какие есть варианты, чтобы фокус оставался в ловушке, но было трудно определить, какие директивы были бы наиболее полезными для этой проблемы. Ниже приведен 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>

Если у кого-то, кто читает это, есть решение этой проблемы, я был бы признателен за вашу помощь.


person TheAtomicPeter    schedule 01.07.2020    source источник


Ответы (1)


Я столкнулся с проблемой смены вкладок. Решение для меня состояло в том, чтобы добавить прослушиватель нажатия клавиш, который предотвращает фокус, если путь события не находится в модальном режиме:

@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.modalIsOpen — это this.document.body.classList.contains('modal-open'), this.modalComponentTagName — это 'app-donate-modal', а this.focusOnFirstElementInModal() фокусируется на кнопке закрытия модального окна.

person ge022    schedule 31.07.2020