使用 VirtualKeyboard API 进行完全控制

Browser Support

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

Source

平板电脑或手机等设备通常具有用于输入文字的虚拟键盘。 与始终存在且始终相同的实体键盘不同,虚拟键盘会根据用户的操作显示和消失,并且还可以动态调整,例如根据 inputmode 属性进行调整。

这种灵活性是以浏览器布局引擎必须了解虚拟键盘的存在并可能需要调整文档布局以进行补偿为代价的。例如,用户即将开始输入的输入字段可能会被虚拟键盘遮挡,因此浏览器必须滚动该字段以使其显示在视图中。

过去,浏览器会自行应对这一挑战,但更复杂的应用可能需要更好地控制浏览器的行为。例如,在多屏移动设备上,如果虚拟键盘仅显示在一个屏幕段上,传统方法会导致屏幕空间“浪费”,但两个屏幕上的可用视口都会缩小。下图展示了如何使用 VirtualKeyboard API 动态优化文档布局,以弥补虚拟键盘的存在。

传统方法会导致

在上述情况下,VirtualKeyboard API 就能派上用场。它包含三个部分:

  • navigator 对象上的 VirtualKeyboard 接口,用于通过 JavaScript 以程序化方式访问虚拟键盘。
  • 一组 CSS 环境变量,用于提供有关虚拟键盘外观的信息。
  • 一种虚拟键盘政策,用于确定是否应显示虚拟键盘。

当前状态

VirtualKeyboard API 可在桌面设备和移动设备上使用,但需要 Chromium 94 及更高版本。

功能检测和浏览器支持

如需检测当前浏览器是否支持 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 指定,前任编辑 Grisha Lyukshin(同样来自 Microsoft)也做出了贡献。