移动端踩坑记---------ios下输入法遮挡input

移动端踩坑记———ios下输入法遮挡input

  最近项目中遇到了一个比较严重移动端IOS下的Fixed兼容问题,网上也有很多人躺在这个问题上了,现在开始详细讨论一下这个问题.

  现在我们先来看一张图,网上有的,暂时先拿来用一下:图片出处


移动端踩坑记---------ios下输入法遮挡input_第1张图片

  其实还会有一种情况的出现


移动端踩坑记---------ios下输入法遮挡input_第2张图片

  这是我遇到的问题的情景,因为项目中我们的项目是一个活动的即时聊天室.所以,需要项目一开始用的是一个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布局解决方案

你可能感兴趣的:(javascript)