android虚拟键导致h5页面位移的根本原因是系统将虚拟导航栏高度计入window.innerheight,使真实可视区域变小;需用uni.onwindowresize监听视口变化、动态设置padding-bottom,并结合scrollintoview解决输入框遮挡问题。

Android虚拟键导致H5页面位移的根本原因
不是页面写错了,而是Android系统在计算window.innerHeight时把底部虚拟导航栏(返回键、主页键)的高度也混进去了。真实可视区域比window.innerHeight小,键盘弹起后页面按“错误高度”重排,就出现底部元素被顶飞、fixed定位失效、输入框被遮挡等问题。
用uni.onWindowResize监听真实视口变化
Android H5下window.resize事件能触发,但iOS不触发——所以这个方案只针对Android有效,且必须配合判断系统类型使用。
- 在
onLoad中先缓存原始windowHeight:uni.getSystemInfoSync().windowHeight - 监听
uni.onWindowResize,当res.size.windowHeight明显变小时(比如小于原始值的90%),认为键盘已弹出 - 此时可动态设置
body或根容器的padding-bottom,值为原始windowHeight - 当前windowHeight - 键盘收起后,
res.size.windowHeight恢复,再清掉padding-bottom
softinputMode在H5端完全无效,别白配
pages.json里app-plus.softinputMode只对App端生效,H5端根本读不到这个配置。很多开发者反复改"adjustResize"或"adjustPan"却没效果,就是卡在这儿——H5没有原生软键盘管理机制,它走的是浏览器视口逻辑。
- H5必须靠JS监听+CSS干预,不能依赖
pages.json配置 - 若同时支持App和H5,需用条件编译:
#ifdef H5块里写JS方案,#ifndef H5里才配softinputMode -
adjust-position属性对H5也无效,它是小程序专属
获取真实键盘高度要减去虚拟键干扰
直接用uni.onKeyboardHeightChange拿到的高度,在部分Android机型上会包含虚拟导航栏高度,导致偏大。得先算出虚拟键真实高度再修正:
- 用
uni.getSystemInfoSync()拿到screenHeight和windowHeight - 虚拟键高度 =
screenHeight - windowHeight(这个值在App端稳定,H5端需实测) - 键盘弹起时监听到的高度 - 虚拟键高度 ≈ 真实键盘高度
- 注意:某些定制ROM(如华为EMUI)可能返回异常值,建议加容错:
Math.max(0, keyboardHeight - virtualKeyHeight)
最麻烦的不是算不准,而是不同Android机型虚拟键高度不统一——有的24px,有的48px,有的甚至没有。所以最终方案往往得结合padding-bottom动态调整 + scrollIntoView强制滚动到输入框,二者缺一不可。











