能力 · API
VirtualKeyboard API
发布于
navigator.virtualKeyboard 让页面接管屏幕键盘弹出时浏览器通常自动完成的布局工作。把 overlaysContent 设为 true 后浏览器不再压缩视口,geometrychange 事件与 boundingRect 报告键盘所在位置,六个 keyboard-inset-* CSS 环境变量把同一个矩形暴露给样式表,show() 与 hide() 则为标记了 virtualkeyboardpolicy="manual" 的可编辑元素请求键盘。
该接口在 Chrome 94 与 Edge 94 中发布,Opera、Samsung Internet、Android WebView 与 Meta Quest Browser 镜像同一实现。Firefox(Bugzilla 1730568)与 Safari(WebKit bug 230225)均未实现(BCD api.VirtualKeyboard)。在没有系统屏幕键盘的设备上,对象存在但 boundingRect 始终为零,geometrychange 不会触发。
navigator.virtualKeyboard.overlaysContent = truenavigator.virtualKeyboard.boundingRectnavigator.virtualKeyboard.show()navigator.virtualKeyboard.hide()navigator.virtualKeyboard.addEventListener('geometrychange', handler).composer { padding-bottom: env(keyboard-inset-height, 0px);}show() 与 hide() 返回 undefined,并以异步方式生效:浏览器请求系统显示或隐藏键盘,等待完成,更新 boundingRect,然后触发 geometrychange。boundingRect 是相对布局视口、以 CSS 像素计的 DOMRect;keyboard-inset-top、-right、-bottom、-left、-width、-height 六个环境变量由同一个矩形更新,键盘从未出现过时读作 0px。VirtualKeyboard 只暴露在 Window 上。
该接口有两个属性、两个方法和一个事件。show() 与 hide() 不接受参数;它们的前提条件列在各自条目里,因为不满足前提的调用会被直接丢弃而没有异常。
| 成员 | 类型 | 说明 |
|---|---|---|
overlaysContent |
boolean,默认 false |
为 true 时,浏览器不得为键盘调整文档视口或视觉视口的尺寸;键盘覆盖在页面之上,页面根据 boundingRect 自行调整位置。只在顶层浏览上下文中生效。 |
boundingRect |
DOMRect(只读) |
当前键盘矩形;键盘隐藏时全部为零。 |
show() |
undefined |
请求显示键盘。除非窗口拥有 sticky activation、焦点元素是表单控件或编辑宿主、该元素带有 virtualkeyboardpolicy="manual"、且其 inputmode 不是 none,否则被忽略。 |
hide() |
undefined |
在同样的激活与 virtualkeyboardpolicy="manual" 条件下收起键盘。 |
geometrychange 事件 |
Event(event.target.boundingRect) |
键盘显示、隐藏或尺寸变化且 boundingRect 更新后触发。 |
可编辑元素上的 virtualkeyboardpolicy 内容属性取值 auto(默认:聚焦元素即显示键盘)或 manual(由页面自己调用 show());inputmode="none" 无论策略如何都会抑制键盘。
无。
setter 与两个方法都不抛出。前提条件不满足的 show() 或 hide() 直接返回;在 iframe 内给 overlaysContent 赋值会被 setter 接受但不产生效果。Chromium 把这两种情况报告为控制台警告,而不是异常。
两个示例都检测 'virtualKeyboard' in navigator。缺失时保留浏览器的默认行为(压缩视口),并借助 Firefox 91 与 Safari 13 都实现的 window.visualViewport 得知键盘占去了多少空间。
把消息输入框固定在键盘上方
Section titled “把消息输入框固定在键盘上方”聊天输入框应当紧贴键盘上沿,而不是随页面滚走。有 API 时页面退出视口压缩,并按键盘高度给输入框加内边距;没有 API 时输入框跟随视觉视口的底边。
const composer = document.querySelector('.composer');
if ('virtualKeyboard' in navigator) { navigator.virtualKeyboard.overlaysContent = true; navigator.virtualKeyboard.addEventListener('geometrychange', (event) => { const { height } = event.target.boundingRect; composer.style.setProperty('--keyboard-height', `${height}px`); });} else if (window.visualViewport) { const vv = window.visualViewport; vv.addEventListener('resize', () => { const covered = window.innerHeight - vv.height - vv.offsetTop; composer.style.setProperty('--keyboard-height', `${Math.max(0, covered)}px`); });}.composer { position: fixed; bottom: 0; padding-bottom: var(--keyboard-height, env(keyboard-inset-height, 0px));}这条 CSS 回退链意味着:支持环境变量但尚未触发 geometrychange 的浏览器仍得到 0px,既没有 API 也没有该变量的浏览器则得到普通的固定输入框。
为基于 canvas 的编辑器唤起键盘
Section titled “为基于 canvas 的编辑器唤起键盘”画在 <canvas> 上的电子表格没有可聚焦的 <input>,于是它放一个隐藏的、带 virtualkeyboardpolicy="manual" 的 contenteditable 元素,并在单元格被点按时调用 show()。没有该 API 的浏览器回退为聚焦该元素,由默认的 auto 策略显示键盘。
<div id="cell-input" contenteditable="true" virtualkeyboardpolicy="manual" inputmode="text"></div>const input = document.querySelector('#cell-input');const canvas = document.querySelector('canvas');
canvas.addEventListener('pointerup', () => { input.focus(); if ('virtualKeyboard' in navigator) { navigator.virtualKeyboard.show(); // 这次点按提供了 sticky activation }});
document.querySelector('#done').addEventListener('click', () => { if ('virtualKeyboard' in navigator) { navigator.virtualKeyboard.hide(); } else { input.blur(); // 默认策略:失去焦点即收起键盘 }});由于 show() 依赖该策略属性,从标记里删掉 virtualkeyboardpolicy="manual" 会让这次调用悄悄变成空操作而没有报错;属性与调用要放在一起维护。
- Media Session API,另一项 Chromium 先行的系统 UI 集成
- Window Management API,关于屏幕而非键盘的几何问题
- PWA 的 Core Web Vitals:LCP、INP 与 CLS,键盘引起的视口压缩在那里表现为布局偏移
- VirtualKeyboard API: the VirtualKeyboard interface(w3c.github.io)
- Full control with the VirtualKeyboard API(developer.chrome.com)
- Bugzilla 1730568: Implement the VirtualKeyboard API(bugzilla.mozilla.org)
- WebKit bug 230225: Implement the VirtualKeyboard API(webkit.org)
规范
| 规范 | 状态 |
|---|---|
| VirtualKeyboard API: the VirtualKeyboard interface | W3C 草案 |
| VirtualKeyboard API: overlaysContent attribute | W3C 草案 |