不能直接用 position: fixed,因微信/支付宝小程序中 fixed 在 scroll-view 内或滚动时会错位、脱离视口,且各端键盘行为不一致:小程序为覆盖式弹出,app 会压缩 webview,h5 无系统键盘事件;需动态监听平台专属键盘高度变化并防抖处理。

uni-app 实现微博式详情页底部固定评论输入框,核心是「避开原生导航栏 + 适配各端键盘弹起 + 输入框不被遮挡」。直接用 position: fixed 在多数小程序(尤其微信)会失效或错位,必须结合平台特性处理。
为什么不能直接用 position: fixed?
微信小程序、支付宝小程序等对 fixed 支持有限:在 scroll-view 内部或页面滚动时,fixed 元素可能脱离视口、跟随滚动、或被键盘顶起后错位。H5 和 App 端表现也不一致——App 中 input 聚焦时系统键盘会压缩 webview 高度,但小程序里是“覆盖式”弹出,无自动 resize。
- 微信小程序中,
input聚焦时会触发keyboardHeight变化,但仅限于mp-weixin平台 - App 端(
app-plus)需监听plus.keyboard.getHeight()手动计算避让高度 - H5 端无系统键盘事件,只能靠
focusin/focusout+window.innerHeight差值估算
uni.getSystemInfoSync().windowHeight 怎么用才可靠?
不能只取一次静态值。窗口高度在键盘弹起/收起时会变(尤其 App 和部分小程序),必须动态监听。推荐做法是:在 onReady 初始化基础高度,再通过平台专属 API 订阅变化。
- 微信小程序:监听
uni.onKeyboardHeightChanged(仅mp-weixin支持) - App 端:用
plus.keyboard.addEventListener('show', ...)+plus.keyboard.getHeight() - H5:监听
window.addEventListener('focusin', ...)到input元素,再比对innerHeight变化 - 所有平台都建议加防抖,避免频繁重绘导致卡顿
如何让输入框始终停在「可视区域底部」而非「页面底部」?
关键不是固定在 bottom: 0,而是锚定在「当前可视区域底部减去键盘高度」的位置。需要一个响应式 bottom 值,由 JS 动态控制 CSS 变量或内联样式。
- 定义一个响应式变量:
data: { inputBottom: '0px' } - 键盘弹起时,设为
inputBottom = keyboardHeight + 'px'(注意:这是从底部向上抬升的距离,所以实际样式是bottom: inputBottom) - 键盘收起时,设为
'0px' - 模板中写:
<view class="comment-input" :style="{ bottom: inputBottom }"></view> - 务必给父容器加
position: relative,否则bottom会相对于 viewport 计算,出错
输入框被键盘遮挡的常见坑
最常被忽略的是:没有关闭页面级下拉刷新或滚动穿透。当键盘弹起,用户若继续下拉,页面滚动会导致输入框移位甚至消失。
- 微信小程序:在
pages.json当前页面配置中,确保"disableScroll": true(防止 scroll-view 滚动干扰) - 所有平台:
input聚焦时,手动调用uni.pageScrollTo({scrollTop: 9999})把内容顶到顶部,避免输入框被盖住 - App 端特别注意:
plus.webview.currentWebview().setStyle可临时禁用滚动,但需在键盘收起后恢复 - 不要用
scroll-view包裹整个页面再放输入框——它和fixed天然冲突
真正难的不是写样式,而是判断「此刻键盘是否已完全展开」「当前平台是否上报了准确高度」「页面是否还在惯性滚动」。这些状态要组合校验,单靠一个事件监听远远不够。











