使用虚拟键盘 API 处理内容遮挡

2022年3月1日

平板电脑和手机等设备通常配备虚拟键盘用于文本输入。与物理键盘不同,虚拟键盘并非一直显示,其出现与隐藏取决于用户的操作或相关属性设置(例如 inputmode 属性)。

然而,这种灵活性要求浏览器的布局引擎能够感知虚拟键盘的状态,并据此调整文档布局。例如,虚拟键盘弹出时可能遮挡输入框,浏览器需要自动滚动页面,确保输入框处于可见区域。

通常情况下,浏览器会自动处理虚拟键盘的显示,而无需向开发者暴露具体细节,常见的处理方式包括:

  1. 将页面内容定位到虚拟键盘上方。
  2. 缩小视口高度,防止内容被键盘遮挡。
  3. 缩小可视视口并扩展布局视口,使内容移至键盘上方。

虚拟键盘 API 允许浏览器保持布局和可视窗口不变,同时向开发者提供虚拟键盘和视口的详细信息,以便通过 JavaScript 或 CSS 环境变量自定义布局。

双屏设备与虚拟键盘

虚拟键盘 API 包含三个部分:

  1. 位于 navigator 对象上的 VirtualKeyboard 接口,用于 JavaScript 控制。
  2. CSS 环境变量,用于描述虚拟键盘的外观。
  3. 虚拟键盘策略,控制键盘的显示行为。

浏览器支持探测

以下代码可检测浏览器是否支持 VirtualKeyboard API:

123if ('virtualKeyboard' in navigator) {  // 浏览器支持 VirtualKeyboard API}

使用 VirtualKeyboard API

VirtualKeyboard API 通过 navigator 对象提供 VirtualKeyboard 接口。

使用虚拟键盘覆盖模式

若希望浏览器自行处理虚拟键盘遮挡问题,首先需将 overlaysContent 属性设为 true

1navigator.virtualKeyboard.overlaysContent = true;

显示和隐藏虚拟键盘

调用 show() 方法可显示虚拟键盘。焦点需位于表单控件(如 textarea)或可编辑元素(如设置了 contenteditable 的元素)上。该方法返回 undefined,并触发 geometrychange 事件。

1navigator.virtualKeyboard.show();

调用 hide() 方法可隐藏虚拟键盘。该方法同样返回 undefined,并触发 geometrychange 事件。

1navigator.virtualKeyboard.hide();

geometrychange 事件

当虚拟键盘出现或消失时,会触发 geometrychange 事件。事件目标为 VirtualKeyboard 实例,可通过 boundingRect 获取几何信息(DOMRect):

1234navigator.virtualKeyboard.addEventListener('geometrychange', (event) => {  const { x, y, width, height } = event.target.boundingRect;  console.log('虚拟键盘几何信息变更:', x, y, width, height);});

获取当前几何信息

通过 boundingRect 属性可获取虚拟键盘的当前几何尺寸。该属性以 DOMRect 对象形式暴露键盘的大小和位置:

12const { x, y, width, height } = navigator.virtualKeyboard.boundingRect;console.log('虚拟键盘几何信息:', x, y, width, height);

CSS 环境变量

VirtualKeyboard API 提供了一组 CSS 环境变量,用于描述虚拟键盘的外观。这些变量类似于 inset 属性,对应上、右、下、左四个方向:

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

环境变量定义了虚拟键盘与可视窗口各边缘之间的距离。

常见用法如下:

123456789101112131415.some-class {  /**   * 若虚拟键盘显示,则使用其高度对应的外边距;   * 否则使用备用值 `50px`。   */  margin-block-end: env(keyboard-inset-height, 50px);}.some-other-class {  /**   * 若虚拟键盘显示,则使用其高度对应的外边距;   * 否则使用默认备用值 `0px`。   */  margin-block-end: env(keyboard-inset-height);}

虚拟键盘策略

virtualkeyboardpolicy 属性控制虚拟键盘是否自动显示,可选值为 automanual

123456789<!-- 仅在双击时显示虚拟键盘 --><div  contenteditable  virtualkeyboardpolicy="manual"  inputmode="text"  ondblclick="navigator.virtualKeyboard.show();">  双击此处进行编辑。</div>

参考链接

评论

0 条讨论

匿名评论需填写昵称、邮箱,并通过人机验证。邮箱不会公开展示,提交后需审核通过才会显示。

还没有评论,来抢沙发吧。