最近在做docmost的二次开发,需要对H5上做一些适配。遇到的第一个问题就是在IOS下软键盘弹出时,页面底部的fixed元素位置不正确的问题。

虽然过去做过一些响应式开发,但是从来没有涉及到这种输入框+fixed元素的“组合拳”,尤其现在是对富文本编辑器进行H5上的适配。要兼容不同设备和不同版本,仿佛回到了过去兼容IE的日子。这时候我才想到了那些跨端方案的好。

但是docmost是web项目,只能硬着头皮兼容了。网上的解决方案五花八门,不同人遇到的场景和项目都迥然不同,这就导致方案不一定是可行的。这时候问AI也无济于事,它只告诉这是IOS下常见的问题,以及一些没用的解决方案。有网友还总结了系列文章https://juejin.cn/post/7148986270369185799

背后的原因是IOS软键盘出现之后,webview会向上偏移。

在测试了不同的方案,研究了飞书文档的实现后,我直接说结论吧(整个过程就是枯燥的测试、分析和踩坑)。

  1. 将布局调整了,html、body高度设置层100vh,内容分为上中下三部分,上下fixed固定,中间主体内容滚动。
  2. 兼容viewpoint的resize时间,如果变小,说明软键盘出现了,重新计算fixed元素的位置
  3. 监听主体的滚动事件,重新计算fixed元素的问题。

最后加上一些优化,比如滚动的节流,元素消失和出现的动画,整体效果还是可以的。

被折磨之后,我去看了看ReactNative是怎么处理的。React Native 处理 iOS 软键盘的核心方式是通过 官方 Keyboard 模块第三方库协作 ,结合事件监听与布局调整。

Keyboard 模块用于监听键盘状态变化,支持以下事件:

  • keyboardWillShow:软键盘即将显示;
  • keyboardDidShow:软键盘已完全显示;
  • keyboardWillHide:软键盘即将隐藏;
  • keyboardDidHide:软键盘已完全隐藏 。

在ReactNative中还有react-native-troika ,它有一个KeyboardInsetsView 组件,可自动处理软键盘遮挡输入框的问题,无需手动计算高度或调整布局。还挺不错的,可惜我这边用不了。

在移动端适配docmost这种重交互的web应用,还是有一定挑战的。挑战不在于技术难度,而在对不同设备的兼容,包括样式、功能和交互,其折磨程度不亚于兼容IE。