使用 VirtualKeyboard API 进行完全控制

浏览器支持

  • 94
  • 94
  • x
  • x

平板电脑或手机等设备通常都有用于输入文字的虚拟键盘。 与始终存在且始终相同的物理键盘不同,虚拟键盘会出现 和消失,具体取决于用户的操作,它也可以动态适应 基础模型, inputmode 属性。

这种灵活性的代价是浏览器布局引擎必须获知 并可能需要将文档布局调整为 获得补偿。例如,用户要输入的输入字段可能会被 虚拟键盘,因此浏览器必须将其滚动到用户视野范围内。

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

传统方法

对于这种情况,Virtual 键盘 API 大显身手。它包含三个部分:

  • navigator 对象的 VirtualKeyboard 接口,用于以编程方式访问虚拟 从 JavaScript 键盘切换。
  • 一组 CSS 环境变量,用于提供有关虚拟键盘的 外观。
  • 虚拟键盘政策,用于确定是否应显示虚拟键盘。

当前状态

在桌面设备和移动设备上,Chromium 94 均提供了 Virtual 键盘 API。

功能检测和浏览器支持

如需检测当前浏览器是否支持 Virtualkeyboard API,请使用以下代码段:

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

使用 Virtualkeyboard API

Virtual 键盘 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 环境变量

Virtual 键盘 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)。请务必浏览 源代码,了解其实现方式。 虽然可以在 iframe 嵌入中观察 geometrychange 事件,但实际的虚拟键盘 行为需要在单独的浏览器标签页中打开演示版。

致谢

Virtual 键盘 API 由 Microsoft 的 Anupam Snigdha 指定,其贡献由 曾是 Microsoft 的编辑 Grisha Lyukshin。主打图片提供方 @freestocks 不启动