Angular Material 17+ 高級教程 – CDK Accessibility の Focus

介紹

CDK Focus 是對原生 DOM focus 的上層封裝和擴展。

Focus Origin

原生 DOM focus 我們只能知道 element 被 focus 了,但是無法知道它是怎麼被 focus 的,但 CDK Focus 可以。

比如說,有一個 button,我們呢有三種方式可以 focus 它:

  1. 用 mouse 點擊這個 button

  2. 用 keyboard tab

  3. 用 Script -- button.focus()

CDK Focus 在監聽到 focus 後,會附帶一個 origin 值,這個 origin 就闡明瞭 focus 的來源

touch (觸屏) 和 mouse 代表用戶點擊了按鈕導致了 focus。

keyboard 指的是用戶按鍵 tab 導致了 focus。

program 表示是程序 Script 導致了 focus。

Descendant Focused

DOM focus 和 blur 不支持冒泡,所以無法監聽子孫 element 的 focus 和 blur 事件。

通常我們會改用 focusin 和 focusout,因爲它們支持冒泡。

或者用 focus + capture 提早捕獲然後再自行判斷。

這些繁瑣的事情,CDK Focus 都替我們封裝好了,只要告訴它我們是否要監聽子孫 focus / blue 就可以了。

 

FocusMonitor

好,知道了它的用途,接着我們來看具體代碼演示。

FocusMonitor 是一個 Root Level Provider,我們需要使用它來監聽 focus 事件。

App Template

<button #button>click</button>

App 組件

export class AppComponent {
  // 1. query button element
  readonly button = viewChild.required('button', { read: ElementRef });

  constructor() {
    // 2. inject FocusMonitor
    const focusMonitor = inject(FocusMonitor);

    afterNextRender(() => {
      // 3. 監聽 focus 事件
      focusMonitor.monitor(this.button().nativeElement).subscribe(origin => {
        // 4. 獲取 focus origin
        console.log('focused', origin);
      });
    });
  }
}

幾個知識點:

  1. DOM Manupulation

    focusMonitor.monitor 算是 DOM Manupulation,它需要 ElementRef 或者 HtmlElement。

    最好是在組件 lifecycle ViewHooks / AfterRenderHooks 階段才執行。

  2. runOutsideAngular
    focusMonitor.monitor 是 ngZone.runOutsideAngular 的,所以 focus 事件不會被 Zone.js 監聽到。
    如果我們在事件 callback 想讓 Angular refreshView 需要自己手動 tick。
    對 Change Detection 不熟悉的朋友,可以複習這篇 Change Detection

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

目錄

上一篇 Angular Material 17+ 高級教程 – Material Ripple

下一篇 TODO

想查看目錄,請移步 Angular 17+ 高級教程 – 目錄

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章