老大给我看了一个展示效果,让我排查一个问题
在我iPhone6s的手机,搜索轻松筹公众号,进入到首页,从首页列表的大病筹款项目随意点击一个进去到详情页,去给这个项目筹款支持,当输入框获取到焦点,点击完成之后。再点击底部的支付按钮点击无效,点击支付按钮的上面确可以吊起支付。很明显这个问题已经影响到我们的支付订单,需要快速定位问题并解决。
定位问题,寻找解决思路
我将问题简单描述后搜索,定位到问题是在iOS上输入框获取到焦点时,软键盘会把fixed元素顶上去。如果是这个问题我将 fixed
定位改为 absolute
,是不是就可以解决。
修改后,测试发现并没有解决问题,可见软键盘并不仅仅是将 fixed
元素顶上去,也把 absolute
顶上去了。也有可能是其它问题造成的。
初级解决方案
后来寻得一个解决方案,将页面主题内容放到一个盒子里,再将这个盒子放到大盒子里,将大盒子 absolute
定位,脱离文档流。当输入框获取到焦点的时候,将小盒子的高度设置为当前页面的可视区域问题。当输入框失去焦点的时候,将小盒子的高度设置为 auto
。
主结构和逻辑代码如下
// 结构处理
<div class="paycontainer">
<div class="paycontent">
<!-- 页面主体内容 -->
</div>
</div>
// 样式处理 脱离文档流
.paycontainer {
position: absolute;
top: 0;
left: 0;
width: 100%;
overflow-y:scroll;
padding-bottom: 65px;
-webkit-overflow-scrolling: touch;
overflow-scrolling: touch;
.paycontent {
height: auto;
}
}
// 逻辑处理 输入框获取焦点和失去焦点的处理
$('#money-input').focus(function() {
$('.paycontent').height($(window).height()+'px');
});
$('#money-input').blur(function() {
$('.paycontent').height('auto');
});
这样处理确实可以解决这个问题。就高高兴兴去测试完上线。
再次碰到类似问题
后来一个同事的活动专题页也出现了这个问题,他的场景时是在弹窗中有输入框吊起软键盘出现的问题。而且他的是弹窗是动态插入的,所以不太方便通过结构处理。
我同事打算通过监听键盘的调起和隐藏来处理,他尝试这么去做,好像并没有解决。后来从原理上分析。
安卓调出软键盘的时候,会将弹窗盖住,这里需要将弹窗主题内容往上调。ios的机制是,调出软键盘的时候,会将主题内容往上推,将input框以及下面的按钮顶上去。不管是上面的textarea还是下面的input输入框,它们任意一个获得焦点的时候,手机的软键盘都会抬起将fixed定位于屏幕最低端的“提交”按钮顶上去,大多数ios手机在软键盘收起的时候都可以将推上去的部分拉来,有时候拉不下拉,对于拉不下来的就出问题了。虽然看上去视图没调整,但是位置都偏上,实际上用户在操作的时候,就点击不了要点击的按钮了。
我的小伙伴想到一个方法,当输入框失去焦点的时候将推上去的拉下来,设置body的 scrollTop 为0,这真是一个好办法,百使不爽。
终极方案
解决输入框input获取焦点得时,虚拟键盘会把fixed元素顶上去的终极解决方法。
// ios 软键盘弹出时 body的scrollTop 设为0
if(checkIOS()){
$UI.on('blur', 'input', function() {
$('body').scrollTop(0);
})
}
// 检测ios系统
function checkIOS() {
let u = navigator.userAgent;
let isIOS =!!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/);
return isIOS;
}