• h5实现输入框fixed定位在屏幕最底部兼容性


    1、问题由来

    做h5 已经有很长一段时间了,现在做的工作h5比pc上的更多,曾经解决pc端IE各个版本的兼容性也是伤透脑筋,原以为h5的会更好,殊不知,还有更头疼的问题,当设计师要设计一个聊天窗口,把输入框定位在最底部,这是再常见不过的问题了吧,举例:

    上图就是我最近做的一个功能,原以为是很简单的一个定位功能,但是没想到牛逼的测试居然用各种iphone,各种安卓,各种浏览器(qq浏览器、safari、opera等浏览器),各种输入法(系统自带、搜狗输入法),测出来一大堆问题,最后经过千辛万苦,终于做到了能大致兼容。

     2、初步解决

    1)、结构布局于第一次解决

     1 //1部分css
     2 .header {
     3      100%;
     4     height: 40px;  
     5 }
     6 //2部分
     7 .body {
     8     100%;
     9    overflow: auto;
    10 }
    11 //3部分
    12 .footer {
    13      100%;
    14     height: 30px;position: fixed; bottom:0;left:0;right:0;
    15 }
    1 <div class="header" id="header">会话问诊</div>
    2 <div class="body" id="body"></div>
    3 <div class="footer" id="footer">
    4      <input type="text" id="input">
    5 </div>
    1 $('.body').css('height', $(window).height() - 39); 
    2 $('#input').on('focus', function () {
    3    setTimeout(function () {
    4                  window.scrollTo(0, 1000000);
    5     }, 200);
    6  });

    这种布局方法就让中间".body"中的内容在".body"中滚动,对整个html中的body产生了1px的滚动,此处滚动的目的是为了执行"window.scrollTo(0, 1000000);",经过测试,若body没有产生滚动,则这个方法是不会执行的。

    相信很多人都会以 以上的方法解决input在弹出键盘时候的问题,当键盘弹出来后,就让滚动条一直往下面滚直到滚动到最下面,没错,这种措施之后能保证大部分的正常,但是在safari浏览器中就出现了问题,由于safari浏览器下部有一块

    图中是safari浏览器自带的一块标签,当使用以上滚动时,你会发现,他虽然是滚动上去了,但是也会出现一块空白,没错,相当于给你的感觉是滚动上去过多,那么此时,也会被测试打回,是不是感觉很伤心无助,(safari浏览器把下面那块当作了body的东西,他自己实现了一块,把我们的html内容装在了他自己实现的容器里面)

    2)、进一步解决

    经过大量的比较与测试,我发现了一个问题,safari下面的自带输入法根本不用处理,键盘依然可以正常弹出与收起。(ps:safari浏览器没有特别的判断,因此此处判断过于复杂,如有更好的判断,请留言,谢谢!此处之所以判断safari浏览器并不是判断QQ浏览器,是因为测试了opera浏览器的展示等跟QQ浏览器一样,因此此处就判断safari浏览器)

     1 $('input').on('focus', function () {  var agent = navigator.userAgent.toLowerCase();
     2   setTimeout(function () {
     3                 if (agent.indexOf('safari') != -1 && agent.indexOf('mqqbrowser') == -1
     4                     && agent.indexOf('coast') == -1 && agent.indexOf('android') == -1
     5                     && agent.indexOf('linux') == -1 && agent.indexOf('firefox') == -1) {//safari浏览器 6                 } else {//其他浏览器
     7                     window.scrollTo(0, 1000000);
     8                 }
    9             }, 200);
    10 });

    3)、再次优化与解决

    经过以上几步骤,原以为完美无缺的解决方案,可以达到很好的兼容了,可是意外又发生了,测试们用了搜狗输入法来做测试,问题又来了,苹果手机自带的输入法的实现是把body挤上去,搜狗则是在得到focus之后,直接弹出的一块遮罩层,这就导致了问题,此时我们的输入框被挡在了输入法之后,因此又增加了下面的判断与处理,

     1 $('input').on('focus', function () {
     2 setTimeout(function () {
     3                 if (agent.indexOf('safari') != -1 && agent.indexOf('mqqbrowser') == -1
     4                     && agent.indexOf('coast') == -1 && agent.indexOf('android') == -1
     5                     && agent.indexOf('linux') == -1 && agent.indexOf('firefox') == -1) {//safari浏览器
     6                     if(scope.$txtWrap.offset().top-winobj.scrollTop() > document.body.offsetHeight/2) { //说明软键盘遮盖页面
     7                         window.scrollTo(0, winobj.height() - 270);
     8                     }
     9                 } else {//其他浏览器
    10                     window.scrollTo(0, 1000000);
    11                 }
    12             }, 200);
    13 });

    3、解决

    经过几次测试,看似几乎没问题,最后又在iphone5上面的QQ浏览器中用搜狗输入法又测试出了问题,它在第一次点击当input获取到第一次focus事件的时候,window执行了scrollTo方法,第二次,他不再执行,不难发现,系统是以为已经滚动到了下方,因此便不再执行,那么我又增加了一个事件

    $('input').on('blur', function () {
      window.scrollTo(0, 0);
    });

    终于大功告成,基本上解决了现在普遍浏览器中大部分搜狗和自带输入法对模拟fix的input定位问题。

    总结最后解决js为:

     1 $('input').on('focus', function () {
     2     var agent = navigator.userAgent.toLowerCase();
     3   setTimeout(function () {
     4                 if (agent.indexOf('safari') != -1 && agent.indexOf('mqqbrowser') == -1
     5                     && agent.indexOf('coast') == -1 && agent.indexOf('android') == -1
     6                     && agent.indexOf('linux') == -1 && agent.indexOf('firefox') == -1) {//safari浏览器
     7                     if(scope.$txtWrap.offset().top-winobj.scrollTop() > document.body.offsetHeight/2) { //说明软键盘遮盖页面
     8                         window.scrollTo(0, winobj.height() - 270);
     9                     }
    10                 } else {//其他浏览器
    11                     window.scrollTo(0, 1000000);
    12                 }
    13             }, 200);
    14 });
    15 
    16 $('input').on('blur', function () {
    17     var agent = navigator.userAgent.toLowerCase();
    18      setTimeout(function () {
    19                 if (!(agent.indexOf('safari') != -1 && agent.indexOf('mqqbrowser') == -1
    20                     && agent.indexOf('coast') == -1 && agent.indexOf('android') == -1
    21                     && agent.indexOf('linux') == -1 && agent.indexOf('firefox') == -1)) {//非safari浏览器
    22                         window.scrollTo(0, 0);
    23                 }
    24             }, 0);
    25 });

    重中之重,一定要让body产生滚动,不然以上方法依然无法解决。

    最近同事又测出了我的方案对某些手机的不兼容性,所以他给出了另一个解决方案,经测试已经达到了几乎所有手机的兼容,下面提供给大家:

    inputFocus: function (e) {
                var winobj = $(window),
                    scope = this,
                    agent = navigator.userAgent.toLowerCase();
                setTimeout(function () {
                    if (agent.indexOf('safari') != -1 && agent.indexOf('mqqbrowser') == -1
                        && agent.indexOf('coast') == -1 && agent.indexOf('android') == -1
                        && agent.indexOf('linux') == -1 && agent.indexOf('firefox') == -1) {//safra浏览器
                        window.scrollTo(0, 1000000);//先滚动到最底部,再用scrollY得到当前的值,必须延迟 否则拿到的就是1000000
                        setTimeout(function(){
                            window.scrollTo(0, window.scrollY - 45);//45像素 所有浏览器都是这么高
                        }, 50)
                    } else {//其他浏览器
                        window.scrollTo(0, 1000000);
                        // window.scrollTo(0, ++this.scrollNum);
                    }
                }, 200);
            },
    

      

    这是我解决这个问题的过程与实践,若大家有更好的思路,或者发现我这个方式依然无法解决某些问题,请在留言区提出,谢谢!

  • 相关阅读:
    ajax
    文件下载--getOutputStream输出二进制字符
    文件上传功能实现代码
    java动态生成验证码
    项目中用到的jar包简介(2)
    python字符串的常见操作
    python切片使用方法(超详细)
    for循环结合range使用方法
    python使用while循环实现九九乘法表
    石家庄云修科技有限公司
  • 原文地址:https://www.cnblogs.com/bo-haier/p/6052148.html
Copyright © 2020-2023  润新知