美文网首页
Angular cdk 学习之 Accessibility(al

Angular cdk 学习之 Accessibility(al

作者: tuacy | 来源:发表于2018-12-20 09:02 被阅读84次

           cdk ally里面提供的功能运用场景是 select, menu 这种有 list options 的组件, 负责处理键盘上下按钮时 option active 的逻辑。cdk Accessibility 部分官方文档连接https://material.angular.io/cdk/a11y/overview

           和cdk里面其他功能模块一样,cdk ally使用之前也要provider导入A11yModule模块。

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

    一 ListKeyManager

           ListKeyManager主要做的事情就是去管理一堆的list 里面哪个item处于active状态(active代表一种状态,比如处于活动转换,获取焦点状态等等)。而且ListKeyManager管理的item必须实现ListKeyManagerOption接口。换句话说ListKeyManager用于管理一系列list的item,这些item就是ListKeyManagerOption。通过ListKeyManager来控制那个ListKeyManagerOption对应的item处于active状态。所以咱们先看下ListKeyManagerOption和ListKeyManager里面一些常见的方法,如下:

    1.1 ListKeyManager常用方法

           讲ListKeyManager方法的时候咱们顺带讲下ListKeyManagerOption里面的方法

    1.1.1 ListKeyManagerOption常用方法介绍

    export interface ListKeyManagerOption {
        /** 当前item是否disabled. */
        disabled?: boolean;
        /** 获取当前item对应的label,配合ListKeyManager里面withTypeAhead函数的使用
         *  适用于输入框的情况,比如输入框下面有一些list item。当输入框输入字符的时候list item 里面的active
         *  item 和输入的文字匹配
         */
        getLabel?(): string;
    }
    

    1.1.2 ListKeyManager常用方法介绍

    export declare class ListKeyManager<T extends ListKeyManagerOption> {
        /**
         * tab 按键的时候触发的
         */
        tabOut: Subject<void>;
        /** 当ListKeyManager里面的list item ,active item 改变的时候触发*/
        change: Subject<number>;
        /**
         * 设置那些ListKeyManager管理的list里在移动(比如tab 按键切换)过程中那些item需要跳过。
         */
        skipPredicate(predicate: (item: T) => boolean): this;
        /**
         * 设置是否循环移动(当active item是最好一个的时候,继续下一个跳到第一个)
         */
        withWrap(shouldWrap?: boolean): this;
        /**
         * active item 移动方向垂直(对应键盘方向键的 上下按键)
         */
        withVerticalOrientation(enabled?: boolean): this;
        /**
         * active item 移动方向水平(对应键盘方向键的 左右按键)
         */
        withHorizontalOrientation(direction: 'ltr' | 'rtl' | null): this;
        /**
         * 用来处理组合按键的情况,比如 altr + 方向键的时候。同样达到方向按键的效果
         */
        withAllowedModifierKeys(keys: ListKeyManagerModifierKey[]): this;
        /**
         * 设置typeahead 模式 配合ListKeyManagerOption的getLabel()函数使用,一般用于配合有输入框的情况下使用,比如输入框输入一个字符,active item 会自动设置到包含这个字符item
         */
        withTypeAhead(debounceInterval?: number): this;
        /**
         * 设置 active item 对应的index
         */
        setActiveItem(index: number): void;
        /**
         * 设置 active item 对应的item
         */
        setActiveItem(item: T): void;
        /**
         * 设置按键
         */
        onKeydown(event: KeyboardEvent): void;
        /** 当前active item 对应的事件 */
        readonly activeItemIndex: number | null;
        /** 当前active item 对应的item */
        readonly activeItem: T | null;
        /** 设置第一个位置的item 为active item(当然了如果第一个item 是disable,则设置第二个) */
        setFirstItemActive(): void;
        /** 设置最后一个位置的item 为 active item */
        setLastItemActive(): void;
        /** 设置下一个item 为active item */
        setNextItemActive(): void;
        /** 设置上一个item 为active item */
        setPreviousItemActive(): void;
        /**
         * 设置active item,但是不产生其他的效果
         */
        updateActiveItem(index: number): void;
        /**
         * 设置active item,但是不产生其他的效果
         */
        updateActiveItem(item: T): void;
    }
    

    1.2 ListKeyManager的使用

           接下来咱们通过ListKeyManager的两个具体继承类ActiveDescendantKeyManager和FocusKeyManager来说明ListKeyManager的具体使用。其实ActiveDescendantKeyManager里面管理的item必须实现Highlightable接口、FocusKeyManager里面管理的item必须实现FocusableOption。

    1.2.1 ActiveDescendantKeyManager的使用

           ActiveDescendantKeyManager里面管理的list item 必须实现Highlightable接口。

    ActiveDescendantKeyManager继承了ListKeyManager类,Highlightable实现了ListKeyManagerOption接口

           ActiveDescendantKeyManager使用场景:如果想ListKeyManager管理的list里面active的item标记为活动状态,其他的标记为非活动状态情况下使用。而且每个item都必须实现Highlightable接口。接下来咱们通过一个具体的实例来简单的说明下。

    咱们自定义一个item组件ItemActiveOptionComponent,这个组件实现Highlightable接口。组件里面做的事情也很简单就是去改变active item的class样式。

    import {Component, HostBinding, Input} from '@angular/core';
    import {Highlightable} from "@angular/cdk/a11y";
    
    @Component({
        selector: 'app-item-active-option',
        template: `
            <div [class.disabled]="disabled">
                <ng-content></ng-content>
            </div>
        `,
        styles: [`
            .active {
                background-color: lightblue;
                color: #fff;
            }
    
            .disabled {
                opacity: 0.3;
            }
        `]
    })
    export class ItemActiveOptionComponent implements Highlightable {
        @Input() item;
        @Input() disabled = false;
        private _isActive = false;
    
        @HostBinding('class.active') get isActive() {
            return this._isActive;
        }
    
        /**
         * 设置 active对应的class
         */
        setActiveStyles() {
            this._isActive = true;
        }
    
        /**
         * 设置非active对应的class
         */
        setInactiveStyles() {
            this._isActive = false;
        }
    
        getLabel() {
            return this.item.name;
        }
    }
    
    
    

    cdk-active-descendant.component.less文件,组件对应样式

    .form-control {
      display: block;
      width: 100%;
      height: calc(2.25rem + 2px);
      padding: .375rem .75rem;
      font-size: 1rem;
      line-height: 1.5;
      color: #495057;
      background-color: #fff;
      background-clip: padding-box;
      border: 1px solid #ced4da;
      border-radius: .25rem;
      transition: border-color .15s ease-in-out, box-shadow .15s ease-in-out;
    }
    
    .form-control:focus {
      color: #495057;
      background-color: #fff;
      border-color: #80bdff;
      outline: 0;
      box-shadow: 0 0 0 0.2rem rgba(0,123,255,.25);
    }
    
    
    .list-group-item:first-child {
      margin-top: 1rem;
      border-top-left-radius: .25rem;
      border-top-right-radius: .25rem;
    }
    
    .list-group-item  {
      position: relative;
      display: block;
      padding: .75rem 1.25rem;
      margin-bottom: -1px;
      background-color: #fff;
      border: 1px solid rgba(0, 0, 0, .125);
    }
    
    .list-group-item:last-child {
      margin-bottom: 0;
      border-bottom-right-radius: .25rem;
      border-bottom-left-radius: .25rem;
    }
    
    .list-group-item.active  {
      z-index: 2;
      color: #fff;
      background-color: #007bff;
      border-color: #007bff;
    }
    

    ActiveDescendantKeyManager的使用,咱们放在这个组件里面实现。ActiveDescendantKeyManager里面管理的item就是咱们上面自定义的ItemActiveOptionComponent。具体的实现可以看下代码。

    import {AfterViewInit, Component, QueryList, ViewChildren} from '@angular/core';
    import {ItemActiveOptionComponent} from "./active-item-option/item-active-option.component";
    import {ActiveDescendantKeyManager} from "@angular/cdk/a11y";
    
    @Component({
        selector: 'app-cdk-active-descendant',
        template: `
            <!-- 输入框 -->
            <div class="form-group">
                <input class="form-control" placeholder="Search..." (keyup)="onKeyDown($event)" #input>
            </div>
    
            <section class="list-group">
                <!-- ActiveDescendantKeyManager要管理的item -->
                <app-item-active-option *ngFor="let user of users | filter: 'name' : input.value; index as index"
                                        [item]="user" class="list-group-item">
                    {{user.name}}
                </app-item-active-option>
            </section>
        `,
        styleUrls: ['cdk-active-descendant.component.less']
    })
    export class CdkActiveDescendantComponent implements AfterViewInit {
    
        /**
         * 找到所有的item(ListKeyManagerOption - Highlightable)
         */
        @ViewChildren(ItemActiveOptionComponent) items: QueryList<ItemActiveOptionComponent>;
        // list item source list
        users = [
            {
                "id": "5b902934d965e7501f4e1c6f",
                "name": "Caroline Hodges"
            },
            {
                "id": "5b9029348f7eed8b6f5f02db",
                "name": "Delores Rivas"
            },
            {
                "id": "5b9029346f48c8407c64d0d5",
                "name": "Darlene Franklin"
            },
            {
                "id": "5b9029341eff315fa87f9e21",
                "name": "Alfreda Love"
            },
            {
                "id": "5b9029342e8917c6ccdb9865",
                "name": "Marcy Ratliff"
            },
            {
                "id": "5b9029349dbb48013460e01f",
                "name": "Beulah Nielsen"
            },
            {
                "id": "5b902934f4f1586e5e72d74a",
                "name": "Morton Kerr"
            },
            {
                "id": "5b9029347918bb204bf7014e",
                "name": "Autumn Tillman"
            },
            {
                "id": "5b902934b86f80e1fc60c626",
                "name": "Diane Bennett"
            },
            {
                "id": "5b9029348999f59215020349",
                "name": "June Eaton"
            }
        ];
    
        private keyManager: ActiveDescendantKeyManager<ItemActiveOptionComponent>;
    
        ngAfterViewInit() {
            // new ActiveDescendantKeyManager
            this.keyManager = new ActiveDescendantKeyManager(this.items)
                .withWrap() // 循环
                .withTypeAhead(); // 支持搜索
    
        }
    
        onKeyDown(event) {
            // 传递事件进去
            this.keyManager.onKeydown(event);
        }
    }
    
    
    ActiveDescendantKeyManager.gif

    1.2.2 FocusKeyManager的使用

           FocusKeyManager里面管理的item必须实现FocusableOption接口。

    FocusKeyManager继承了ListKeyManager类,FocusableOption实现了ListKeyManagerOption接口

           FocusKeyManager使用场景:如果想ListKeyManager管理的list里面active item想直接接受到浏览器的焦点focus的时候使用。每个item都必须实现FocusableOption接口。

    自定义一个组件ItemFocusOptionComponent,并且这个组件实现了FocusableOption接口,FocusableOption接口的focus()方法里面设置当前item获取焦点。

    import {Component, ElementRef, HostBinding, Input} from '@angular/core';
    import {FocusableOption, FocusOrigin} from "@angular/cdk/a11y";
    
    @Component({
        selector: 'app-item-focus-option',
        template: `
            <ng-content></ng-content>
        `,
        styles: [
                `:host:focus {
                background: lightblue;
                color: #fff;
            }`
        ]
    })
    
    export class ItemFocusOptionComponent implements FocusableOption {
        @Input() item;
    
        /**
         * 屏蔽掉默认的键盘事件,js里面自己控制键盘事件
         */
        @HostBinding('tabindex') tabindex = '-1';
    
        constructor(private host: ElementRef) {
        }
    
        getLabel() {
            return this.item.name;
        }
    
        /**
         * 设置获取焦点
         */
        focus(origin?: FocusOrigin): void {
            this.host.nativeElement.focus();
        }
    }
    
    

    cdk-focus.component.less 样式文件

    .form-control {
      display: block;
      width: 100%;
      height: calc(2.25rem + 2px);
      padding: .375rem .75rem;
      font-size: 1rem;
      line-height: 1.5;
      color: #495057;
      background-color: #fff;
      background-clip: padding-box;
      border: 1px solid #ced4da;
      border-radius: .25rem;
      transition: border-color .15s ease-in-out, box-shadow .15s ease-in-out;
    }
    
    .form-control:focus {
      color: #495057;
      background-color: #fff;
      border-color: #80bdff;
      outline: 0;
      box-shadow: 0 0 0 0.2rem rgba(0,123,255,.25);
    }
    
    
    .list-group-item:first-child {
      margin-top: 1rem;
      border-top-left-radius: .25rem;
      border-top-right-radius: .25rem;
    }
    
    .list-group-item  {
      position: relative;
      display: block;
      padding: .75rem 1.25rem;
      margin-bottom: -1px;
      background-color: #fff;
      border: 1px solid rgba(0, 0, 0, .125);
    }
    
    .list-group-item:last-child {
      margin-bottom: 0;
      border-bottom-right-radius: .25rem;
      border-bottom-left-radius: .25rem;
    }
    
    .list-group-item.focus {
      z-index: 2;
      color: #fff;
      background-color: #007bff;
      border-color: #007bff;
    }
    

    FocusKeyManager的具体使用

    import {AfterViewInit, Component, QueryList, ViewChildren} from '@angular/core';
    import {FocusableOption, FocusKeyManager} from "@angular/cdk/a11y";
    import {ItemFocusOptionComponent} from "./focus-item-option/item-focus-option.component";
    
    @Component({
        selector: 'app-cdk-focus',
        template: `
            <section class="list-group" (keyup)="onKeyDown($event)">
                <app-item-focus-option *ngFor="let user of users; index as index"
                                       [item]="user" class="list-group-item"
                                       (click)="selectItem(index)">
                    {{user.name}}
                </app-item-focus-option>
            </section>
        `,
        styleUrls: ['./cdk-focus.component.less']
    })
    export class CdkFocusComponent implements AfterViewInit {
    
        // 获取搜有实现了FocusableOption接口的item
        @ViewChildren(ItemFocusOptionComponent) items: QueryList<ItemFocusOptionComponent>;
        // list source
        users = [
            {
                "id": "5b902934d965e7501f4e1c6f",
                "name": "Caroline Hodges"
            },
            {
                "id": "5b9029348f7eed8b6f5f02db",
                "name": "Delores Rivas"
            },
            {
                "id": "5b9029346f48c8407c64d0d5",
                "name": "Darlene Franklin"
            },
            {
                "id": "5b9029341eff315fa87f9e21",
                "name": "Alfreda Love"
            },
            {
                "id": "5b9029342e8917c6ccdb9865",
                "name": "Marcy Ratliff"
            },
            {
                "id": "5b9029349dbb48013460e01f",
                "name": "Beulah Nielsen"
            },
            {
                "id": "5b902934f4f1586e5e72d74a",
                "name": "Morton Kerr"
            },
            {
                "id": "5b9029347918bb204bf7014e",
                "name": "Autumn Tillman"
            },
            {
                "id": "5b902934b86f80e1fc60c626",
                "name": "Diane Bennett"
            },
            {
                "id": "5b9029348999f59215020349",
                "name": "June Eaton"
            }
        ];
    
        private keyManager: FocusKeyManager<ItemFocusOptionComponent>;
    
        ngAfterViewInit() {
            // 创建FocusKeyManager对象
            this.keyManager = new FocusKeyManager(this.items)
                .withWrap()
                .withTypeAhead();
    
        }
    
        /**
         * 传递按键事件
         * @param event
         */
        onKeyDown(event) {
            this.keyManager.onKeydown(event);
        }
    
        /**
         * 点击选中
         * @param index
         */
        selectItem(index: number) {
            this.keyManager.setActiveItem(index);
        }
    
    }
    
    
    FocusKeyManager.gif

    二 FocusTrap

           FocusTrap是cdk ally模块里面提供的一个指令。用于捕获元素中的Tab键焦点。同时控制焦点的范围,Tab切换焦点的时候不会跳出这个区域。举个例子比如有一个视图元素添加了FocusTrap指令,这个视图元素里面有三个input。这样Tab键切换焦点的时候焦点会在这三个input之间切换。

           Selector: [cdkTrapFocus]

           Exported as: cdkTrapFocus

           还有几个其他的指令可以配合FocusTrap指令来使用:cdkFocusRegionStart、cdkFocusRegionEnd、cdkFocusInitial。咱们上面不是说了FocusTrap指令会控制焦点的范围。cdkFocusRegionStart和cdkFocusRegionEnd指令有可以进一步的控制焦点的范围

    • cdkFocusRegionStart:FocusTrap范围的起点
    • cdkFocusRegionEnd:FocusTrap范围的终点
    • cdkFocusInitial:区间出现时,一开始获取focus的item。

    2.1 FocusTrap指令属性介绍

    FocusTrap属性 类型 解释
    autoCapture: boolean @Input('cdkTrapFocusAutoCapture') 初始化的时候元素是否自动获取焦点
    enabled: boolean @Input('cdkTrapFocus') false Tab切换焦点的时候会跑到外面去,true Tab切换焦点的时候焦点不会跑到外面去

    2.2 FocusTrap指令使用

    import {Component} from '@angular/core';
    
    @Component({
        selector: 'app-cdk-accessibility',
        template: `
            <!-- FocusTrap的使用,- 控制焦点的范围,tab切换焦点的时候不会跳出这个区域 -->
            <div cdkTrapFocus style="border: solid 1px #ccc; padding: 10px">
                <!-- Tab and Shift + Tab will not leave this element. -->
                <input placeholder="Email">
                <input type="password" placeholder="Password" style="margin-left: 10px">
                <button type="submit" style="margin-left: 10px">Submit</button>
            </div>
        `
    })
    export class CdkAccessibilityComponent {
    }
    
    

    2.3 cdkFocusRegionStart cdkFocusRegionEnd cdkFocusInitial的使用

           cdkFocusRegionStart和cdkFocusRegionEnd的使用应该很好理解。就是用来控制范围的。关键是cdkFocusInitial的使用,cdkFocusInitial必须要配合cdkTrapFocus指令的cdkTrapFocusAutoCapture=true使用。而且我试了下cdkFocusInitial一开始是没有效果,没都是隐藏显示的时候才有效果,才获取到焦点。

    import {Component} from '@angular/core';
    
    @Component({
        selector: 'app-cdk-accessibility',
        template: `
            <div *ngIf="displayFocusTrap" cdkTrapFocus cdkTrapFocusAutoCapture="true"
                 style="border: solid 1px #ccc; padding: 10px; margin-top: 10px">
                <input value="1">
                <input style="margin-left: 10px" value="2" cdkFocusRegionStart>
                <input style="margin-left: 10px" value="3" cdkFocusInitial>
                <input style="margin-left: 10px" value="4" cdkFocusRegionEnd>
            </div>
            <button (click)="displayFocusTrap=!displayFocusTrap">显示</button>
        `
    })
    export class CdkAccessibilityComponent {
    
        displayFocusTrap = false;
    
    }
    
    
    
    

    三 FocusMonitor

           FocusMonitor是cdk ally里面提供的一个Service。用于监控焦点。FocusMonitor里面常用方法如下

    export declare class FocusMonitor implements OnDestroy {
    
        /**
         * 监听元素的焦点获取
         */
        monitor(element: HTMLElement, checkChildren?: boolean): Observable<FocusOrigin>;
        monitor(element: ElementRef<HTMLElement>, checkChildren?: boolean): Observable<FocusOrigin>;
        /**
         * 停止监听元素的焦点获取
         */
        stopMonitoring(element: HTMLElement): void;
        stopMonitoring(element: ElementRef<HTMLElement>): void;
        /**
         * 设置元素获取焦点
         * @param element 元素
         * @param origin 设置的焦点是通过哪个来的 'touch' | 'mouse' | 'keyboard' | 'program' | null
         * @param options 用于配置focus行为的选项.
         */
        focusVia(element: HTMLElement, origin: FocusOrigin, options?: FocusOptions): void;
        focusVia(element: ElementRef<HTMLElement>, origin: FocusOrigin, options?: FocusOptions): void;
    }
    

    3.1 FocusMonitor的使用

           一个简单的例子,咱们仅仅是在元素获取焦点的时候做一个简单的打印。

    import {AfterViewInit, Component, ElementRef, OnDestroy} from '@angular/core';
    import {FocusMonitor} from "@angular/cdk/a11y";
    
    @Component({
        selector: 'app-cdk-focus-monitor',
        template: `
            <div cdkTrapFocus style="border: solid 1px #ccc; padding: 10px; margin-top: 10px">
                <input value="FocusMonitor item 1">
                <input style="margin-left: 10px" value="FocusMonitor item 2">
                <input style="margin-left: 10px" value="FocusMonitor item 3">
                <input style="margin-left: 10px" value="FocusMonitor item 4">
            </div>
        `
    })
    export class CdkFocusMonitorComponent implements AfterViewInit, OnDestroy {
    
        constructor(private _elementRef: ElementRef,
                    private _focusMonitor: FocusMonitor) {
        }
    
        ngAfterViewInit() {
            /**
             * 这里我们只是做了一个简单的打印
             */
            this._focusMonitor.monitor(this._elementRef.nativeElement, true).subscribe(mode => {
                console.log('元素获取到焦点 focused 来源 ' + mode);
            });
        }
    
        ngOnDestroy() {
            this._focusMonitor.stopMonitoring(this._elementRef.nativeElement);
        }
    
    }
    
    

    四 FocusTrapFactory

           FocusTrapFactory也是cdk ally里面提供的一个Service。他的功能就是用来给元素添加cdkFocusTrap指令。FocusTrapFactory常用函数就一个,如下

    export declare class FocusTrapFactory {
        /**
         * 给指定的元素添加cdkFocusTrap指令,deferCaptureElements参数正好对应cdkFocusTrap指令
         * @Input('cdkTrapFocusAutoCapture')功能
         */
        create(element: HTMLElement, deferCaptureElements?: boolean): FocusTrap;
    }
    

    4.1 FocusTrapFactory使用

           通过FocusTrapFactory的crete函数达到cdkFocusTrap指令的效果。

    import {AfterViewInit, Component, ElementRef} from '@angular/core';
    import {FocusTrap, FocusTrapFactory} from "@angular/cdk/a11y";
    
    @Component({
        selector: 'app-cdk-focus-trap-factory',
        template: `
            <div style="border: solid 1px #ccc; padding: 10px; margin-top: 10px">
                <input value="FocusTrapFactory item 1">
                <input style="margin-left: 10px" value="FocusTrapFactory item 2">
                <input style="margin-left: 10px" value="FocusTrapFactory item 3">
                <input style="margin-left: 10px" value="FocusTrapFactory item 4">
            </div>
        `
    })
    export class CdkFocusTrapFactoryComponent implements AfterViewInit {
    
        private _focusTrap: FocusTrap;
    
        constructor(private _elementRef: ElementRef,
                    private _focusTrapFactory: FocusTrapFactory) {
        }
    
        ngAfterViewInit() {
            this._focusTrap = this._focusTrapFactory.create(this._elementRef.nativeElement);
        }
    
    }
    
    

    五 InteractivityChecker

           InteractivityChecker是一个Service,用于检查元素的一些状态。常见方法如下。

    export declare class InteractivityChecker {
        /**
         * 元素是否 disabled.
         */
        isDisabled(element: HTMLElement): boolean;
        /**
         * 元素是否visible
         *
         * This will capture states like `display: none` and `visibility: hidden`, but not things like
         * being clipped by an `overflow: hidden` parent or being outside the viewport.
         *
         * @returns Whether the element is visible.
         */
        isVisible(element: HTMLElement): boolean;
        /**
         * 元素是否接受Tab按键,不如Tab按键切换焦点
         */
        isTabbable(element: HTMLElement): boolean;
        /**
         * 元素是否可以获取焦点
         */
        isFocusable(element: HTMLElement): boolean;
    }
    

    5.1 InteractivityChecker使用

           举一个非常简单的例子,打印出button的各种状态。

    import {Component, ElementRef, OnInit, ViewChild} from '@angular/core';
    import {InteractivityChecker} from "@angular/cdk/a11y";
    
    @Component({
        selector: 'app-cdk-interactivity-checker',
        template: `
            <button #interactivityCheckerButton>InteractivityChecker测试</button>
            <p>上面button是否disable: {{disable}}</p>
            <p>上面button是否visible: {{visible}}</p>
            <p>上面button是否可以tabable: {{tabable}}</p>
            <p>上面button是否可以focusable: {{focusable}}</p>
        `
    })
    export class CdkInteractivityCheckerComponent implements OnInit {
    
        @ViewChild('interactivityCheckerButton') button: ElementRef;
        disable: boolean;
        visible: boolean;
        tabable: boolean;
        focusable: boolean;
    
        constructor(private _interactivityChecker: InteractivityChecker) {
        }
    
        ngOnInit() {
            this.disable = this._interactivityChecker.isDisabled(this.button.nativeElement);
            this.visible = this._interactivityChecker.isVisible(this.button.nativeElement);
            this.tabable = this._interactivityChecker.isTabbable(this.button.nativeElement);
            this.focusable = this._interactivityChecker.isFocusable(this.button.nativeElement);
        }
    
    }
    
    

    六 LiveAnnouncer

           LiveAnnouncer也是一个Service。用于在屏幕上发布一个消息。把消息显示在屏幕上。关于这一部分的内容估计的去看下W3C关于WAI-ARIA的使用。我们就举一个简单的例子。

    import {Component} from '@angular/core';
    import {LiveAnnouncer} from "@angular/cdk/a11y";
    
    @Component({
        selector: 'app-cdk-live-announcer',
        template: `
        `
    })
    export class CdkLiveAnnouncerComponent {
    
        index = 1;
    
        /**
         * 会在屏幕上输出Hey Google,三秒之后又会换成Hey Google 2
         */
        constructor(private liveAnnouncer: LiveAnnouncer) {
            liveAnnouncer.announce("Hey Google");
            setTimeout(() => {
                this.timerTask();
            }, 3000);
        }
    
        timerTask() {
            this.index = this.index + 1;
            this.liveAnnouncer.announce("Hey Google " + this.index.toString(), "off");
        }
    
    }
    
    

           关于cdk ally咱们就扯这么多,希望能对大家有点帮助。当然了里面很有很多其他的类咱们没有介绍到。大家在时机使用的时候可以对照官方文档看下 https://material.angular.io/cdk/a11y/overview。 文章中涉及到的例子连接地址 https://github.com/tuacy/angular-cdk-study

    相关文章

      网友评论

          本文标题:Angular cdk 学习之 Accessibility(al

          本文链接:https://www.haomeiwen.com/subject/iuuekqtx.html