pages.json中softinputMode必须写在具体页面style的app-plus下,仅对App平台生效;值必须为"adjustResize"以触发WebView高度压缩重排,配合adjust-position和cursor-spacing才能彻底解决键盘遮挡问题。

pages.json 里 softinputMode 必须写在 app-plus 的页面级 style 下
这个配置只对 App 平台(iOS/Android)生效,且必须写在具体页面的 style 对象里,不能塞进全局 manifest.json 或小程序/H5 配置块中。常见翻车点是把它丢进 "mp-weixin" 或 "h5" 字段下,结果日志里完全没反应。
正确写法示例:
{
"path": "pages/form/form",
"style": {
"app-plus": {
"softinputMode": "adjustResize",
"softinputNavBar": "none"
}
}
}
- •
"softinputMode": "adjustResize" 是唯一能触发 WebView 高度压缩的值,"adjustPan" 只会平移整个页面,遮挡问题照旧•
"softinputNavBar": "none" 建议一并加上,尤其 iOS 上能干掉键盘上方那条带“完成”按钮的横条,减少干扰• 修改后必须重启 HBuilderX 或重新运行 App,热更新不生效
adjustResize 为什么比 adjustPan 更适合表单页
adjustResize 会让 WebView 容器高度随键盘收缩,触发真实重排;而 adjustPan 只是把整个 Webview 当作一张图往上推,fixed 元素、导航栏、底部按钮全跟着飘走——你看到的“输入框没被盖住”,其实是它被系统硬顶到了屏幕中间。
适用场景很明确:
- • 表单类页面(登录、注册、资料编辑),需要顶部标题+中间滚动区+底部提交按钮都保持可见
• 页面用了
flex: 1 或 height: 100vh 布局,配合 overflow-y: auto 才能滚动补位• 不想让用户手动拖动找输入框,也不接受“页面突然变矮”的割裂感
注意:adjustResize 在 H5 和小程序里无效,它们压根不认这个配置。
为什么加了 adjustResize 还要配 adjust-position 和 cursor-spacing
光靠 softinputMode: "adjustResize" 只解决了容器层行为,但原生 <input> 组件是否响应、光标是否贴边,还得靠组件级开关。
三者必须共存才稳:
- •
adjust-position="true":App 端的“允许调整”总开关,缺它 cursor-spacing 就是摆设•
cursor-spacing="100":不是留白越多越好,80–120 是实测最稳区间;设太小(如 20)光标紧贴键盘看不清,设太大(如 300)页面猛蹿• 必须用原生
<input> 或 <textarea></textarea> 标签,u-input 等封装组件大概率透传失败别信“加了就自动好”,iOS 老机型或百度输入法仍可能忽略,得靠 uni.onKeyboardHeightChange 监听兜底。
监听 keyboardHeight 时最容易漏掉的两件事
uni.onKeyboardHeightChange 是跨端唯一可靠入口,但直接用很容易崩:
- • 别在
mounted 里注册监听——页面未激活时注册,进页面前就触发,高度值错乱• 每次
@blur 必须调 uni.offKeyboardHeightChange(),否则多次进出页面,监听器叠成堆,keyboardHeight 被反复赋值,页面抖动H5 端根本不会触发这个事件,得另走 window.addEventListener('resize') + 高度差判断;<web-view></web-view> 里的输入框也完全不响应,它跑在独立内核里,只能靠 pages.json 里配 softinputMode 强制接管。
真正难的不是写几行代码,而是让不同平台、不同输入法、不同机型在键盘弹起收起那一瞬间,都刚好做对一件事——这得靠配置、监听、兜底三层咬合,少一层就露馅。


















