使用 VirtualKeyboard API 完全控管

瀏覽器支援

  • 94
  • 94
  • x
  • x

平板電腦或手機等裝置通常都有可輸入文字的虛擬鍵盤。與一律顯示且一律相同的實體鍵盤不同,虛擬鍵盤會根據使用者動作顯示及消失,且也可以根據 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>

示範模式

您可以在 Glitch 的示範中查看 VirtualKeyboard API 的實際運作情形。請務必探索原始碼,瞭解如何實作。雖然 iframe 內嵌項目可以觀察 geometrychange 事件,但實際的虛擬鍵盤行為需要在自己的瀏覽器分頁中開啟示範模式。

特別銘謝

VirtualKeyboard API 是由 Microsoft 的 Anupam Snigdha 指定,與 Microsoft 先前編輯者 Grisha Lyukshin 的貢獻相同。主頁橫幅由 @freestocks 顯示在 Unsplash 上。