H5 平台不支持 uni.onKeyboardHeightChange,仅 App 和部分小程序可用;H5 应优先使用 uni.onWindowResize 监听视口变化,结合初始 windowHeight 判断键盘弹起/收起,并用 setTimeout 延时 80ms 调用 uni.pageScrollTo 归位。

uni.onKeyboardHeightChange 在 H5 下根本不会触发
这是最常被忽略的前提:H5 平台不支持 uni.onKeyboardHeightChange,它只对 App(iOS/Android)和部分小程序生效。你在 H5 页面里写这个监听,等于没写——控制台不会报错,但回调永远不会执行。别浪费时间调试它。
真正可用的 H5 方案只有两个:uni.onWindowResize 和手动比对 window.innerHeight。前者在 Android Chrome、微信内置浏览器中基本可靠;后者更底层,但需注意安卓 WebView 内核版本差异导致的触发时机不准(比如某些低版本 UC 浏览器 resize 会延迟 200ms+)。
- 优先用
uni.onWindowResize,它比 DOM 的window.addEventListener('resize')更稳定,能捕获键盘弹起/收起引发的视口变化 - 避免直接监听
focus/blur:Android 下blur常常滞后或丢失,尤其在快速切换输入框时 - 不要依赖
document.documentElement.clientHeight:它在部分安卓 WebView 中始终返回屏幕高度,不随键盘变化
如何判断 keyboard 弹出后页面是否被“顶起”
核心逻辑是:键盘弹出 → 视口高度变小 → 但页面整体未缩容 → 导致底部 fixed 元素被挤出可视区。关键不是“有没有键盘”,而是“当前可视高度是否小于初始高度”。
初始化时必须缓存原始 windowHeight,且要在 onLoad 里调用 uni.getSystemInfo 获取,不能用 document.body.offsetHeight 或 screen.height —— 后者是物理屏幕高度,完全不反映布局上下文。
- 记录初始值:
this.baseHeight = res.windowHeight - 监听变化:
uni.onWindowResize(res => { const current = res.size.windowHeight; if (current - 加 100px 容差:避免因横竖屏切换、状态栏显示/隐藏等微小变化误判
fixed 元素被顶飞?别修 CSS,改布局结构
在 Android H5 中,position: fixed 是个幻觉。键盘弹出时,浏览器只是缩小了可视区域,但 fixed 元素仍锚定在“原始 viewport 底部”,而用户看到的是被裁剪后的画面——所以它看起来飘在半空。强行用 transform 或 top 补偿,会在键盘收起时留下定位残留。
远程控制 Android 设备,支持截图、自动化操作手机 App 等功能。本应用使用 uiautomator2 作为底层框架,通过 ADB 连接设备,用户无需 Root(1)查看手机屏幕;(2)自动化操作手机 App;(3)远程安装/卸载应用……
正确做法是放弃 fixed,改用流式布局:
- 父容器设
display: flex; flex-direction: column; height: 100vh; - 内容区加
flex: 1; overflow-y: auto;,确保可滚动 - 底部操作栏用
height: 60px;(固定值)或min-height: 60px;,不设position - 如果必须动态预留键盘高度,用
:style="{ paddingBottom: keyboardHeight + 'px' }",其中keyboardHeight来自onWindowResize差值估算
为什么键盘收起后页面卡在高位?
这不是 bug,是 Android 浏览器的“懒加载”行为:键盘收起后,视口高度恢复,但页面 scrollTop 没有自动归零,且浏览器不会主动触发 scroll 事件。用户看到的“卡住”,其实是页面还停在之前键盘弹出时滚动到的位置。
最稳妥的修复是在 onWindowResize 回调里加一个“收起判定”:
- 当
res.size.windowHeight > this.baseHeight - 50时,认为键盘已收起 - 用
setTimeout(() => { uni.pageScrollTo({ scrollTop: 0, duration: 0 }); }, 80)强制归位 - duration 设为 0,避免动画干扰;延时 80ms 是为了等浏览器完成视口重绘,太短(如 0ms)可能无效
这个延时值在多数安卓机型上足够,但如果你的应用要兼容老旧 WebView(比如 Android 5.x 的系统浏览器),可能需要提到 120ms。

















