使用 VirtualKeyboard API 完全控管

Browser Support

  • Chrome: 94.
  • Edge: 94.
  • Firefox: not supported.
  • Safari: not supported.

Source

平板電腦或手機等裝置通常會提供虛擬鍵盤,方便使用者輸入文字。 實體鍵盤會一直存在且一成不變,但虛擬鍵盤會根據使用者的動作顯示和隱藏,並動態調整,例如根據 inputmode 屬性。

但這種彈性會造成瀏覽器的版面配置引擎必須得知虛擬鍵盤的存在,並可能需要調整文件的版面配置來補償。舉例來說,使用者即將輸入內容的輸入欄位可能會遭到虛擬鍵盤遮蔽,因此瀏覽器必須捲動該欄位,讓使用者看見。

傳統上,瀏覽器會自行處理這項挑戰,但較複雜的應用程式可能需要進一步控管瀏覽器的行為。舉例來說,在多螢幕行動裝置上,如果虛擬鍵盤只顯示在一個螢幕區段,傳統做法會導致螢幕空間「浪費」,但兩個螢幕上可用的檢視區塊仍會縮小。下圖顯示如何使用 VirtualKeyboard API 動態調整文件版面配置,以補償虛擬鍵盤的出現。

傳統做法會導致

這時 VirtualKeyboard API 就能派上用場。其中包含三個部分:

  • navigator 物件上的 VirtualKeyboard 介面,可透過 JavaScript 以程式輔助方式存取虛擬鍵盤。
  • 一組 CSS 環境變數,可提供虛擬鍵盤外觀的相關資訊。
  • 這項虛擬鍵盤政策會決定是否顯示虛擬鍵盤。

目前狀態

從 Chromium 94 開始,電腦和行動裝置都可使用 VirtualKeyboard API。

功能偵測和瀏覽器支援

如要偵測目前的瀏覽器是否支援 VirtualKeyboard API,請使用下列程式碼片段:

if ('virtualKeyboard' in navigator) {   // The VirtualKeyboard API is supported! } 

使用 VirtualKeyboard API

VirtualKeyboard API 會在 navigator 物件中新增 VirtualKeyboard 介面。

啟用新的虛擬鍵盤行為

如要告知瀏覽器您會自行處理虛擬鍵盤遮蔽問題,請先將布林值屬性 overlaysContent 設為 true,啟用新的虛擬鍵盤行為。

navigator.virtualKeyboard.overlaysContent = true; 

顯示及隱藏虛擬鍵盤

呼叫虛擬鍵盤的 show() 方法,即可透過程式輔助顯示虛擬鍵盤。如要讓這項功能正常運作,焦點元素必須是表單控制項 (例如 textarea 元素),或是編輯主機 (例如使用 contenteditable 屬性)。這個方法一律會傳回 undefined,但如果先前未顯示虛擬鍵盤,則會觸發 geometrychange 事件。

navigator.virtualKeyboard.show(); 

如要隱藏虛擬鍵盤,請呼叫 hide() 方法。這個方法一律會傳回 undefined,但如果先前顯示虛擬鍵盤,則會觸發 geometrychange 事件。

navigator.virtualKeyboard.hide(); 

取得目前的幾何圖形

您可以查看 boundingRect 屬性,取得虛擬鍵盤的目前幾何圖形。 這個物件會以 DOMRect 物件的形式,公開虛擬鍵盤的目前尺寸。插邊對應於頂端、右側、底部和/或左側屬性。

const { x, y, width, height } = navigator.virtualKeyboard.boundingRect; console.log('Virtual keyboard geometry:', x, y, width, height); 

接收幾何圖形變更通知

虛擬鍵盤顯示或隱藏時,系統會一律分派 geometrychange 事件。事件的 target 屬性包含 virtualKeyboard 物件,該物件 (如上所述) 包含虛擬鍵盤插邊的新幾何圖形,以 DOMRect 形式呈現。

navigator.virtualKeyboard.addEventListener('geometrychange', (event) => {   const { x, y, width, height } = event.target.boundingRect;   console.log('Virtual keyboard geometry changed:', x, y, width, height); }); 

CSS 環境變數

VirtualKeyboard API 會公開一組 CSS 環境變數,提供虛擬鍵盤外觀的相關資訊。這些屬性的模型與 inset CSS 屬性類似,也就是對應於上、右、下和/或左屬性。

  • keyboard-inset-top
  • keyboard-inset-right
  • keyboard-inset-bottom
  • keyboard-inset-left
  • keyboard-inset-width
  • keyboard-inset-height

虛擬鍵盤插邊是六個環境變數,可定義矩形,方法是從可視區域邊緣插入頂端、右側、底部和左側。系統會根據其他插邊計算寬度和高度插邊,方便開發人員使用。如未提供備用值,每個鍵盤插邊的預設值為 0px

您通常會使用環境變數,如下列範例所示:

.some-class {   /**    * Use a margin that corresponds to the virtual keyboard's height    * if the virtual keyboard is shown, else use the fallback value of `50px`.    */   margin-block-end: env(keyboard-inset-height, 50px); }  .some-other-class {   /**    * Use a margin that corresponds to the virtual keyboard's height    * if the virtual keyboard is shown, else use the default fallback value of `0px`.    */   margin-block-end: env(keyboard-inset-height); } 

虛擬鍵盤政策

有時,當可編輯的元素成為焦點時,虛擬鍵盤不應顯示。舉例來說,在試算表應用程式中,使用者可以輕觸儲存格,將其值納入另一個儲存格的公式。virtualkeyboardpolicy 是屬性,關鍵字為字串 automanual。如果指定給contenteditable主機auto元素,則會導致相應的可編輯元素在聚焦或輕觸時自動顯示虛擬鍵盤,並manual將可編輯元素的焦點和輕觸動作與虛擬鍵盤的目前狀態變更分開。

<!-- Do nothing on regular focus, but show the virtual keyboard on double-click. --> <div   contenteditable   virtualkeyboardpolicy="manual"   inputmode="text"   ondblclick="navigator.virtualKeyboard.show();" >   Double-click to edit. </div> 

示範

如要查看 VirtualKeyboard API 的實際應用情形,請參閱示範。請務必探索原始碼,瞭解實作方式。雖然可以在 iframe 嵌入中觀察 geometrychange 事件,但如要查看實際的虛擬鍵盤行為,必須在專屬的瀏覽器分頁中開啟示範

特別銘謝

VirtualKeyboard API 由 Microsoft 的 Anupam Snigdha 指定,並由 Microsoft 的前任編輯 Grisha Lyukshin 貢獻。