最近项目中遇到了一个比较严重移动端IOS下的Fixed兼容问题,网上也有很多人躺在这个问题上了,现在开始详细讨论一下这个问题.
现在我们先来看一张图,网上有的,暂时先拿来用一下:图片出处
其实还会有一种情况的出现
这是我遇到的问题的情景,因为项目中我们的项目是一个活动的即时聊天室.所以,需要项目一开始用的是一个layim的框架(扯句题外话,从中了解了挺多的关于Wokerman的知识,有兴趣的也可以去看看Workerman),每次唤起软键盘的时候都会遮挡一半或者不遮挡的情况.
首先,我们先要知道为什么出现这两种情况,其实是因为在IOS下fixed属性失效了,所以会出现Sticky footer的input乱飞的问题.这个问题随便百度一下都有所谓的解决方案.
1. onresize事件:
直接排除,因为IOS端并不会触发事件,至少我尝试的时候确实是这样
2.定时器方案:出处 :
这个方法在IOS11以下听说有效(我没试过),但是亲测在IOS11下也是失效了,大概意识就是在触发focus
的时候开启定时器,拉到屏幕最低部,然后blur
以后会清除这个定时器.这个试过,我也排除了.
var interval = setInterval(function() {
document.body.scrollTop = document.body.scrollHeight
}, 100)
3.布局重构:
就是别用fixed布局了,用Flex布局,然后使用flex-direction: column
,纵向布局,但是手机屏幕的滚动可能会出现问题:参考方法
因为我们公司一开始就用框架,所以如果我要改布局的话,在时间和人力上都不允许的.所以只能排除,但是我是推荐这种方案.
4.手动计算(我采纳的方案):
就是通过自己计算弹出高度来计算input
到底处于什么位置,然后判断input是否处于对应的位置,如果不在就上移,移动到大概的位置,这个方法的主要缺点是会有一点不自然,大概会有300毫秒的延迟(因为键盘的弹出需要时间,所以需要setTimeout延迟执行).
意思是:IOS中fixed不是失效吗?不是会变成absolute吗?既然这样我就顺着你的absolute进行操作,进行改变位置
现在直接奉上代码:
thatChat.textarea.on('focus', function () {
var _this = this;
//获得屏幕的高度
var $windowHeight = $(window).height();
//vh的计算原理,这个要自己慢慢计算出来
var bili = 51.63 / 100;
//这个是input框应该显示的位置,应为全局变量
maxheight = Math.floor(bili * $windowHeight);
setTimeout(function () {
//框架自己自带的方法,主要用着鉴别设备
if (device.ios || device.os == 'mac') {
//获取页面卷去的高度
var scrollPos = document.body.scrollTop;
//以防出现maxheight计算错误
if (scrollPos > maxheight) {
maxheight = scrollPos;
}
//出现了遮挡的情况,就把footer和主要内容上移
if (scrollPos < maxheight) {
//我自己项目的实际移动距离,根据实际情况移动
$('.layim-chat-footer,.layim-chat-main').css({
'margin-bottom': '12.7vh'
});
}
}
}, 500);
});
thatChat.textarea.on('blur', function () {
//当input失去焦点的时候,取消上移的距离,恢复正常
$('.layim-chat-footer,.layim-chat-main').css({
'margin-bottom': '0'
});
});
具体代码就这些,看起来不复杂,就是操作起来比较麻烦,因为IOS要console.log()
操作需要用到weinre这个软件,慢慢地得出结果,然后算出比例值.才能算出大概input移动距离.vh单位的使用主要是为了适配各种大小的手机,在这个项目中,我试过iphone 5和iphone 6p 都基本可以.主要缺点就是因为有定时器的存在,所以用户体验上会有一点不适.
最后,这个方法虽然是暴力简单,但是我不觉得算是解决方法,只能暂且这么做,因为在限定了框架的情况下只能这么使用了.这个方法我也是加载框架底层源码里面的.
所以在写项目的时候,最好是自己进行布局,不要太过依赖于框架的使用,框架只是一种方便开发的工具,不要太过依赖,限制了自己的发展
另外,在我们写项目的时候希望更多地考虑一下兼容问题,尽量少踩点坑,我这边使用的vh就是一个比较错误的使用,推荐使用rem能更好地适配各种尺寸的设备.
这个问题,暂时没有完美的解决方案,所以还是别用fixed布局吧
推荐方案(虽然我没有尝试过):Flex布局解决方案