介紹
CDK Focus 是對原生 DOM focus 的上層封裝和擴展。
Focus Origin
原生 DOM focus 我們只能知道 element 被 focus 了,但是無法知道它是怎麼被 focus 的,但 CDK Focus 可以。
比如說,有一個 button,我們呢有三種方式可以 focus 它:
-
用 mouse 點擊這個 button
-
用 keyboard tab
-
用 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); }); }); } }
幾個知識點:
-
DOM Manupulation
focusMonitor.monitor 算是 DOM Manupulation,它需要 ElementRef 或者 HtmlElement。
最好是在組件 lifecycle ViewHooks / AfterRenderHooks 階段才執行。
- runOutsideAngular
focusMonitor.monitor 是 ngZone.runOutsideAngular 的,所以 focus 事件不會被 Zone.js 監聽到。
如果我們在事件 callback 想讓 Angular refreshView 需要自己手動 tick。
對 Change Detection 不熟悉的朋友,可以複習這篇 Change Detection
目錄
上一篇 Angular Material 17+ 高級教程 – Material Ripple
想查看目錄,請移步 Angular 17+ 高級教程 – 目錄