How to keep focus within modal dialog?

后端 未结 9 920
醉酒成梦
醉酒成梦 2020-12-17 17:29

I\'m developing an app with Angular and Semantic-UI. The app should be accessible, this means it should be compliant with WCAG 2.0. To reach this p

相关标签:
9条回答
  • 2020-12-17 18:30

    I've been successful using Angular Material's A11yModule.

    Using your favorite package manager install these to packages into your Angular app.

    **"@angular/material": "^10.1.2"**
    
    **"@angular/cdk": "^10.1.2"**
    

    In your Angular module where you import the Angular Material modules add this:

    **import {A11yModule} from '@angular/cdk/a11y';**
    

    In your component HTML apply the cdkTrapFocus directive to any parent element, example: div, form, etc.

    Run the app, tabbing will now be contained within the decorated parent element.

    0 讨论(0)
  • 2020-12-17 18:33

    we can use the focus trap npm package.

    npm i focus-trap

    0 讨论(0)
  • 2020-12-17 18:33

    I used one of the methods suggested by Steven Lambert, namely, listening to keydown events and intercepting "tab" and "shift+tab" keys. Here's my sample code (Angular 5):

    import { Directive, ElementRef, Attribute, HostListener, OnInit } from '@angular/core';
    
    /**
     * This directive allows to override default tab order for page controls.
     * Particularly useful for working around the modal dialog TAB issue
     * (when tab key allows to move focus outside of dialog).
     *
     * Usage: add "custom-taborder" and "tab-next='next_control'"/"tab-prev='prev_control'" attributes
     * to the first and last controls of the dialog.
     *
     * For example, the first control is <input type="text" name="ctlName">
     * and the last one is <button type="submit" name="btnOk">
     *
     * You should modify the above declarations as follows:
     * <input type="text" name="ctlName" custom-taborder tab-prev="btnOk">
     * <button type="submit" name="btnOk" custom-taborder tab-next="ctlName">
     */
    
    @Directive({
      selector: '[custom-taborder]'
    })
    export class CustomTabOrderDirective {
    
      private elem: HTMLInputElement;
      private nextElemName: string;
      private prevElemName: string;
      private nextElem: HTMLElement;
      private prevElem: HTMLElement;
    
      constructor(
        private elemRef: ElementRef
        , @Attribute('tab-next') public tabNext: string
        , @Attribute('tab-prev') public tabPrev: string
      ) {
        this.elem = this.elemRef.nativeElement;
        this.nextElemName = tabNext;
        this.prevElemName = tabPrev;
      }
    
      ngOnInit() {
        if (this.nextElemName) {
          var elems = document.getElementsByName(this.nextElemName);
          if (elems && elems.length && elems.length > 0)
            this.nextElem = elems[0];
        }
    
        if (this.prevElemName) {
          var elems = document.getElementsByName(this.prevElemName);
          if (elems && elems.length && elems.length > 0)
            this.prevElem = elems[0];
        }
      }
    
      @HostListener('keydown', ['$event'])
      onKeyDown(event: KeyboardEvent) {
    
        if (event.key !== "Tab")
          return;
    
        if (!event.shiftKey && this.nextElem) {
          this.nextElem.focus();
          event.preventDefault();
        }
    
        if (event.shiftKey && this.prevElem) {
          this.prevElem.focus();
          event.preventDefault();
        }
    
      }
    
    }
    

    To use this directive, just import it to your module and add to Declarations section.

    0 讨论(0)
提交回复
热议问题