Android H5页面被顶起的根本原因是WebView弹出软键盘时压缩window.innerHeight触发resize事件,但uni-app未响应导致fixed元素上移;adjust-position在H5无效;需监听uni.onWindowResize动态修正bottom值,并对iOS额外用scrollIntoView和padding-bottom处理。

Android H5下页面被顶起的根本原因
Android WebView在软键盘弹出时会压缩window.innerHeight,触发resize事件,但uni-app默认不监听或响应这个变化,导致body或容器高度未重算,fixed元素(如底部输入框)被“硬顶”上移,且失焦后不恢复。这不是bug,是WebView行为与uni-app生命周期脱节的典型表现。
adjust-position在H5端无效,别白费力气
这个属性只对小程序和App生效,H5平台完全忽略:adjust-position="false"。实测v3.9.12及之前所有版本均如此——写上去没报错,但也不起作用。强行加只会误导自己排查方向。
监听resize + 动态修正bottom值
这是目前最稳定、跨Android机型兼容的方案。核心逻辑:记录初始视口高度 → 键盘弹起时window.innerHeight变小 → 算出差值即键盘高度 → 把输入框容器的bottom设为该值 → 失焦时还原为0。
- 必须用
uni.onWindowResize而非window.addEventListener('resize'),否则H5下监听不到 -
@focus里不能直接取window.innerHeight,因为此时键盘尚未完全弹出,值不准;要等onWindowResize回调触发后再计算 - 首次聚焦时
onWindowResize可能延迟触发,建议加setTimeout兜底(50ms足够) - CSS中输入框容器必须是
position: absolute或fixed,否则bottom无效
// template
<view class="input-wrap" :style="{ bottom: inputBottom }">
<input @focus="onFocus" @blur="onBlur" />
</view>
<p>// script
data() {
return {
inputBottom: '0',
initialHeight: 0
}
},
onLoad() {
this.initialHeight = window.innerHeight;
uni.onWindowResize(res => {
const h = window.innerHeight;
if (h < this.initialHeight - 100) { // 过滤微小波动
this.inputBottom = (this.initialHeight - h) + 'px';
} else {
this.inputBottom = '0';
}
});
},
methods: {
onFocus() {
// 不在这里改bottom,留给onWindowResize统一处理
},
onBlur() {
this.inputBottom = '0';
}
}iOS H5需额外处理fixed定位失效
虽然问题问的是Android,但实际项目几乎总会同时跑iOS。iOS Safari不压缩window.innerHeight,所以onWindowResize根本不会触发。此时必须换策略:Element.scrollIntoView({ block: 'nearest' }) + getBoundingClientRect()获取输入框相对视口位置,再动态调整父容器padding-bottom。这点容易被忽略——同一套H5代码在双端表现不同,不能只修一边。
真正麻烦的不是单个平台,而是你得在同一个@focus回调里判断uni.getSystemInfoSync().platform === 'ios',然后走两套逻辑。没做这层判断,就等于没做完。


















