摘要:背景項目中需要對網頁的操作設置快捷鍵,但是我們的開發機是,用戶使用的是。通常和是一致的。規范中說這些過期的屬性會因平臺,鍵盤語言,鍵盤布局等等眾多因素而導致其取值不統一。
背景
項目中需要對網頁的 UI 操作設置快捷鍵,但是我們的開發機是 Mac,用戶使用的是 Windows。所以開發起來遇到一些小小的坑。現在我們來梳理下這些知識點。
基礎知識網頁上要設置快捷鍵最基礎的做法一般是監聽 keydown 事件,然后通過監聽函數參數獲取一些按鍵相關的屬性來判斷用戶按了哪些按鍵:
document.addEventListener( "keydown", function( event ){ let key = event.key; if ( key === "Enter" ) { console.log( "你按下的是回車鍵~" ); } } );
上面的代碼只是做一個示例,按鍵相關的屬性有很多個,這些屬性定義在 KeyboardEvent 這個接口中。keydown 事件監聽函數接受的第一個參數 event 就實現了這個接口(event不僅僅實現了 KeyboardEvent 還實現了其他接口噢)。KeyboardEvent 這個接口是在 W3C 的 DOM 規范里面定義的,現在最新發布的規范版本是 DOM4。不過呢,KeyboardEvent 在 DOM4 中并沒有什么更新,文檔直接把其定義指向了 DOM3 中的 KeyboardEvent 接口定義。所以接下來,讓我們看下規范中是如何定義鍵盤事件的。
KeyboardEvent先介紹下我們常用的一些屬性(規范地址):
KeyboardEvent.key
KeyboardEvent.code
KeyboardEvent.ctrlKey
KeyboardEvent.shiftKey
KeyboardEvent.altKey
KeyboardEvent.metaKey
KeyboardEvent.ctrlKey | shiftKey | altKey | metaKey 比較簡單,表示當你按下鍵盤的時候,Ctrl | Shift | Alt | meta 按鍵是否已經被按下。如果已經被按下這些值就是 true,通常我們要運用組合鍵的判斷會用到(譬如:Alt + a)。大家看到 meta 會疑惑這個是哪個鍵?在 Mac 平臺上指的是 command 鍵(?),而在 Windows 平臺指的是 windows 鍵(?)。但是不是所有 Windows 電腦鍵盤都有 ? 這個鍵的。接下來我們介紹下最重要的兩個屬性 key 和 code。
KeyboardEvent.key如果你按下的按鈕所代表的是一個可打印的字符(printed representation),那么這個 key 的值就是這個字符(譬如:a、Enter、Shift、CapsLock、Backspace)。如果是一些特殊字符呢,這個值就可能是 Unidentified。你要問哪些鍵是特殊字符,這個。。。倫家標準里面說了應鍵盤而異。這里說的是多帶帶按一個按鍵的場景,組合鍵又不同了,key 出什么值是有一套簡單的算法的:
key holds the key value of the key pressed. If the value is has a printed representation, it MUST be a non-empty Unicode character string, conforming to the algorithm for determining the key value defined in this specification.
這里我只介紹最基本的用法,不詳述算法。
KeyboardEvent.code這個值比較詭異,它表示你按了鍵盤上的哪個按鍵。你按 a,code 的值是 KeyA,你按左邊的 Shift,code 的值是 ShiftLeft。什么意思呢?就是他表示你按的按鍵在鍵盤的哪個位置。這里就有趣了,因為不同語言的鍵盤同一個鍵代表的字符可能不同,但是位置是相同的。打個比方:KeyQ 代表的是我們普通鍵盤q按鍵。但是呢 Dvorak 鍵盤q這個位置的按鈕代表的不是 q,而是"。所以如果你按同一個按鈕,key 的值可能不同,code 的值會相同。
有了上述的幾個值一般的單個按鍵和組合鍵都能檢測到了,不過按照 web 標準的尿性你可能會猜到,那兼容性問題呢?查下兼容表。。。key 和 code 兼容性堪憂啊,都是瀏覽器高級版本支持或者根本不支持。那么怎么辦?
非標準屬性KeyboardEvent 接口標準經歷了許多草稿版本,首先在 DOM2 下由于沒有協商一致,它被丟棄; DOM3 重新加入。這導致了在早期的 DOM2 版本中非標準的實現。
KeyboardEvent.char:如果是 printed 的字符,則值是這個字符,如果是按鍵沒有對應的 printed 字符,值為空。(如果該按鍵用作插入多個字符的宏, 則此屬性的值是整個字符串, 而不僅僅是第一個字符。)
KeyboardEvent.charCode:是按鍵字符對應的 Unicode 編碼的數字。(對于其 char 屬性包含多個字符的按鍵是該屬性中第一個字符的 Unicode 值。)
KeyboardEvent.keyCode:返回一個代表你所按按鍵的數字,這個數字是和系統實現相關。
KeyboardEvent.which:通常和 keyCode 是一致的。
DOM3 規范中說這些過期的屬性會因平臺,鍵盤語言,鍵盤布局等等眾多因素而導致其取值不統一。
兼容性如果你要在不同的瀏覽器甚至不同的平臺使用一套快捷鍵,你嘗試上述所有說到的屬性,你會發現表現幾乎都不一致。有的情況是相同按鈕[組合]對應同一個屬性取出的值不同。譬如 Alt + a,當你在 a 按下去的時候去獲取 KeyboardEvent.key 的值,Windows 平臺得到的是a,而 Mac 平臺下得到的是?。有的情況是上述 KeyboardEvent 中很多屬性都不支持,你連挑的機會都沒有,譬如老版本的 IE 幾乎只支持 KeyboardEvent.keyCode 這一個屬性。
經過大量的測試,如果你需要一個大路化通用的解決方案,只能使用 KeyboardEvent.keyCode 來做統一的判斷。當然如果這不能滿足你的要求,那么你可以通過 userAgent 來判斷不同平臺,針對不同平臺采取不同的快捷鍵策略。以上就是對這個知識點的簡單梳理,如果想要更深入的如了解鍵盤事件的模型,請參考下方附上的規范。
參考資料KeyboardEvent from MDN: https://developer.mozilla.org...
KeyboardEvent in DOM3 Events Specification: https://w3c.github.io/uievent...
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/92184.html
摘要:描述最近使用實現了一個遠程桌面監控的應用,分為服務端和客戶端,客戶端可以實時監控服務端的桌面,并且可以通過鼠標和鍵盤來控制服務端的桌面。接下來我們要實現遠程控制,也就是監聽事件,傳遞事件,執行事件這幾部分。 描述 最近使用node實現了一個遠程桌面監控的應用,分為服務端和客戶端,客戶端可以實時監控服務端的桌面,并且可以通過鼠標和鍵盤來控制服務端的桌面。 showImg(https://...
摘要:前言最近在用封裝純數字的輸入框,開發過程中發現不是坑,也有不少值得研究的地方。因此我們能做的是通過事件作事后補救措施在中攔截輸入法中輸入的和按鍵事件,然后自行出發事件執行補救措施。 前言 ?最近在用Polymer封裝純數字的輸入框,開發過程中發現不是坑,也有不少值得研究的地方。本系列打算分4篇來敘述這段可歌可泣的踩坑經歷: [《動手寫個數字輸入框1:input[type=number...
摘要:前言最近在用封裝純數字的輸入框,開發過程中發現不是坑,也有不少值得研究的地方。因此我們能做的是通過事件作事后補救措施在中攔截輸入法中輸入的和按鍵事件,然后自行出發事件執行補救措施。 前言 ?最近在用Polymer封裝純數字的輸入框,開發過程中發現不是坑,也有不少值得研究的地方。本系列打算分4篇來敘述這段可歌可泣的踩坑經歷: [《動手寫個數字輸入框1:input[type=number...
閱讀 2866·2021-11-11 10:58
閱讀 1920·2021-10-11 10:59
閱讀 3489·2019-08-29 16:23
閱讀 2324·2019-08-29 11:11
閱讀 2785·2019-08-28 17:59
閱讀 3838·2019-08-27 10:56
閱讀 2049·2019-08-23 18:37
閱讀 3111·2019-08-23 16:53