ENTER or SPACE, KEYDOWN or KEYUP
前一篇文章作動行為 Activation Behavior 發佈之後,卡西又做了一些測試,發現到 ENTER 和 SPACE 的觸發時機其實不一樣:
終於可以登入 codesandbox 了,在目前的 Chrome, Firefox, Safari 試了一下,結果 enter 會在 keydown 觸發 activation behavior ,但是 space 會在 keyup 觸發 https://t.co/ec1rMlFVvO
-- 卡西 (@caasih) October 21, 2019
然後我仔細測試過發現真的是這樣,而且 SPACE 有keypress
的狀態,就像是滑鼠按鍵按下去但是還沒放開時的樣子,然後這又讓我有點好奇起來了,仔細搜尋一番,發現 web 標準都沒有提到這個細節的定義,唯一有一點關係的是卡西也有找到的 WAI-ARIA Authoring Practices Issue 610,於是我就覺得這應該和 Web 標準定義沒關係,應該是更古老的預設行為,於是改變方向改找 Windows 預設行為相關的文件,搜尋一陣子其實也找不太到東西,大概是因為 GUI 和 Windows 剛出的時候其實 www 還不知道在哪裡吧,不過後來還是找到兩篇 stackoverflow 的問答看起來是相關的:
- Why do Enter and Space keys behave differently for buttons?
- Keyboard control of GUI dialogs - Should default button change with focus?
總和這兩篇的內容,大概整理一下:
這個行為應該是 Windows 一開始的時候就如此設計的了(看起來是很難找到相關設計的文件),然後實際上和 ENTER 相關(相對)的操作其實是 ESC 鍵,ENTER 鍵代表的是直接點 default button(例如 form 的 submit、dialog 的 ok 之類的),或是可以說是執行元件預設的行為,至於 ESC 鍵則是取消,不過取消在網頁的控制元件中幾乎是不存在的,過去有的大概只有<select>
展開下拉選單後又決定不選時可以取消,到 HTML5 則又多了<dialog>
有取消的行為(關閉 dialog),大概也是因為這個原因讓人忽略了 ENTER 和 ESC 的關係,變成注意到 ENTER 和 SPACE 都可以操作元件;至於 SPACE 鍵其實就像是滑鼠點擊,keyDown
如同mouseDown
,keyUp
如同mouseUp
,要到keyUp
才算一個點擊的動作,也就是到這時候才會去觸發click
事件。
搞清楚這現象的原理之後,其實也就更容易理解 WAI-ARIA Authoring Practices 的範例那些 ENTER、ESC、SPACE 幾個按鍵行為為什麼是那樣了,當然,以後需要客製 widget 時也不用再對這幾個按鍵的行為該怎樣定義苦惱了。