ios系统输入框光标错位问题

原文出自:http://www.cnblogs.com/zml-mary/p/7816495.htmlcss

 

 

 

qa测试手机升级之后弹框输入光标出现错位现象,前两天因为时间紧迫,一直没有找到好的解决方案,今天一天都在解决这个bug问题,临近下班终于算比较好的解决这个问题,以为有必要理理~html

引发缘由:弹框的定位采起position:fixed,而ios(safari)对定位属性position:fixed的解析不一致致使。ios

解决方案:app

    方案一iphone

       一开始上网找解决方案,找到以下处理方式。但存在当页面出现滚动条时,弹框弹出后,页面回滚至顶部。在不改变原有弹框代码的状况下,有效地解决光标错位问题,但严重影响用户使用,只能忍痛舍去~布局

      
//弹框弹出后执行以下代码
  $('body').css({'position': 'fixed', 'width': '100%'});
//弹框关闭后执行以下代码
  $('body').css({'position': 'relative'});

  方案二测试

     尝试多种方式后,只能从源头解决,不使用position:fixed。重写弹框定位,但问题是,这个弹框涉及全部页面,后台开发用这弹框作了不少操做,弹框中间内容因为能够自定义,因此是牵一发而动全身,不敢轻易改,就连上传图片的进度条显示都是用这个弹框作的(就是为了套用弹框的一个遮罩效果)spa

    解决思路:code

     1.弹框(#pop )采用position:absolute定位,遮罩(#shadow)采用fixed定位(原先采用absolute定位的,因为有些页面内容是根据用户滚动进行动态加载,致使原先的遮罩不能彻底遮住全部内容,固然也能够对某些元素定高进行加载内容,避免此类问题出现,但此次的修改要考虑通用性,后台开发有时候根本无论你这些,关键目前系统不少页面都已经出现这问题了)htm

   2.弹框采用absolute定位后,关键是top值的肯定(ios10.3 Safari 输入键盘弹出时,若页面底部被挤压上去,则关闭弹框会复原到页面滚动到底部时的状态,若底部没被挤压上去,每弹出一次键盘,页面都会上去必定距离,且不复原)

复制代码
    var initTopH = function() {
        var tempH = $('#pop').height(); //弹框高度
        var screenH = $(window).height();//手机屏幕高度
        var scrollH = $(document).scrollTop();//文档内容滚动高度
        var topH = scrollH + (screenH - tempH) / 2;//top值高度

             //解决当输入键盘未手动关闭时,弹窗的定位问题
          if ($(document).height() - scrollH < screenH) {
               topH = $(document).height() - screenH + (screenH - tempH) / 2;
            }

        return topH;
    };
复制代码

3.觉得这样就能够解决问题,但新的问题出现,当输入框得到焦点时,移动端会弹出键盘挤压弹框上移,关闭键盘后,弹框不会恢复原位,因此须要对弹框失焦后在进行从新定位执行initTopH()

  $("#pop input,textarea").off('blur').on('blur', function() {
    //这里只是对input和textarea处理
            $('#pop').css({'top':initTopH()});
        });

4.  要成功解决一个问题,就会引起更多的问题须要解决,成功操做1-3的操做后,当弹框弹出后,若页面存在滚动条,此时滚动页面,弹框是不会跟着页面下移的,由于top是写死的。想固然是监听页面滚动(scroll)事件,实时改变top值,但问题是效果太差,抖动、弹跳太明显,qa确定会提bug的~

   另外一途径就是弹出弹框后禁止页面滚动,觉得设置body页面overflow:hidden就行了,然而pc端模拟测试有效果,真实环境仍然不起做用。觉得没有给body定高,就都设置html,body标签的高度为100%;但然并卵,反而出现  $(document).scrollTop() 取值有问题(用$('body').scrollTop()替换仍没用,关键pc端模拟都有效果,一到真实环境就出问题),影响前面弹框定位。烦~烦~烦~,反复测试,都没有实质性的进展~

     前面一直纠结于给body定高,但想一想仍是不妥,不少页面开发者给各自页面都会从新定义样式,我这么暴力地修改,担忧影响其余页面布局,因此果断放弃这条路子~

    如何在不影响大局的状况下从新布局呢?忽然想到了阻止默认事件  e.preventDefault() ,可是新问题又来了,使用这个能够很好的解决页面滚动问题,但也会阻止弹框里内容滚动。纠结ing~

5.冥思苦想,采起总体除去局部的思想来监听touchmove事件,方法以下,当触摸对象不是弹框时,阻止默认事件,当触摸对象是弹框时,虽然滚动弹框里的内容出现底部页面也滚动的状况,但触摸结束之后恢复原始的滚动高度,经测试效果还不错,也不以为突兀~

复制代码
        $('#pop').show();
          var sh;//记录初始滚动高度
            $(document).off('touchstart').on('touchstart', function(e) {
            sh = $(document).scrollTop();
        });
        $(document).off('touchmove').on('touchmove', function(e) {
            if (e.target.id === "shadow") {//除去#pop
                e.preventDefault();
            }
        });
        $(document).off('touchend').on('touchend', function(e) {
            $(document).scrollTop(sh);
        });
复制代码

 

总结:虽然可能会有更好的解决方案,但这是我目前以为比较好的处理方式,每一个人所处的开发环境不同,考虑的东西也不一样,因此此方法并不必定都适应,能够借鉴参考。一天都在解决这个bug问题,找资料,尝试各类方法,虽然问题已解决,但仍是想好好理顺下思路,故写下这篇随笔~啦~啦~啦~啦,下班啦~

 

ps:领导说能够看下其余应用的弹框是否有此类问题,看下人家是怎么解决的,但我和小伙伴看了全部app,都没找到相似弹出须要输入文字的弹框(除iphone手机弹出用户输入id密码外),大都是新开一个页面让用户填写,看来产品仍是要往用户习惯上靠~

相关文章
相关标签/搜索