zoukankan      html  css  js  c++  java
  • iScroll4下表单元素聚焦及键盘的异常问题

    问题:在使用了iScroll4的容器内,当表单元素focus聚焦后键盘出现时,可能会存在iScroll区域高度不更新,滚动异常问题;而且当前聚焦的表单元素可能不出现在可视区域内,影响用户体验。

    iKeyboardScroll4就是这么一个解决方案
    Github见:https://github.com/zawaliang/iKeyboardScroll4

    如今大多数机型都支持onorientationchange事件,iScroll4在不支持onorientationchange事件的机型中使用onresize事件来对滚动区域进行自动刷新操作。所以上面说的表单情况,在大多数机型里都会存在高度不刷新的情况。

    1 RESIZE_EV = 'onorientationchange' in window ? 'orientationchange' :'resize',

    那么现在的问题就是检测键盘出现与否,然后调用refresh接口刷新滚动区域高度。由于没有相应的接口来检测键盘状态,所以我们通过onresize来检测窗口高度变化,配合当前元素的聚焦状态来模拟键盘状态。同时需要考虑在键盘出现时翻屏的情况。

    以下为核心函数,用于检测键盘状态:

    1 function detect() {
    2         // 不等表示翻屏
    3         if (_landscape != _landscape2) {
    4             // 屏幕翻转且翻转前键盘处于显示状态时,交换宽高
    5             if (_display) {
    6                 var tmpWidth = _initWinWidth;
    7                 _initWinWidth = _initWinHeight;
    8                 _initWinHeight = tmpWidth;
    9             else {
    10                 _initWinWidth = $(window).width();
    11                 _initWinHeight = $(window).height();
    12             }
    13         }
    14  
    15         var h = $(window).height();
    16         _display = _activeElement !== null && _initWinHeight > h;
    17  
    18         $.each(_callback, function(k, v) {
    19             v.apply(null, [_display, _activeElement]);
    20         });
    21         _landscape = _landscape2;
    22     }

    由于不确定orientationchange与onresize哪个先触发,并且实测发现iOS下orientationchange比onresize迟触发,造成翻屏状态的获取不好捕获,所以针对IOS系统,当翻屏时我们使用orientationchange来检测,其他状态下使用onresize。翻屏状态下,Android下orientationchange之后获取高度存在时间差,所以需要onresize后延时获取进行处理。

    1 $(window).on('orientationchange'function(e) {
    2         _landscape2 = !!(window.orientation & 2);
    3  
    4         // ios下可以直接取宽高,且ios下onresize似乎比orientationchange先触发,因此setTimeout的时机不好掌控
    5         _ios7 && detect();
    6     }).on('resize'function(e) {
    7         // ios下onresize似乎比orientationchange先触发,因此setTimeout的时机不好掌控
    8         // 对于ios,翻屏时统一通过orientationchange进行处理,非翻屏时统一使用onresize
    9         // ios下,onresize后若宽度不相同证明翻屏了,此时使用orientationchange来进行处理
    10         // Android不变,使用onresize处理
    11         if (_ios7
    12             && (_landscape != _landscape2 // 此判断是为了防止orientationchange先于onresize触发
    13                 || $(window).width() != _initWinWidth)) {
    14             return;
    15         }
    16  
    17         _timer && clearTimeout(_timer);
    18         // Android下orientationchange之后获取window值会延时
    19         _timer = setTimeout(detect, 200);
    20     });

    当存在聚焦元素,且窗口高度比初始化时的窗口高度小时,即认为键盘出现了。

    1 _display = _activeElement !== null && _initWinHeight > h;

    键盘的问题解决了,我们需要解决聚焦元素的位置问题,否则可能会出现聚焦元素不在可视区域的情况,用户茫然不知当前输入的是啥。需要注意的是在iOS6下,系统会自动定位到聚焦的元素,但升级后的iOS7,受iScroll影响,造成输入框focus聚焦失败; iOS5.x 6.x下不存在这个问题,具体原因待研究(这里有篇文章不错,可以看下:《运用webkit绘制渲染页面原理解决iscroll4闪动的问题》),所以iOS7下的表现跟Android比较类似,所以我们只对非iOS6以及iOS7的做处理即可。

    1 // 聚焦且键盘显示时,修正输入框位置
    2 // iOS6会自动定位到输入框,但还是需要refresh位置
    3 // iOS7不会自动定位到输入框,表现跟Android类似
    4 if ((!$.os.ios || _ios7)
    5    && display && focusElement) {
    6    offset = $.type(offset) == 'number' ? offset : 5;
    7  
    8    var el = $(focusElement),
    9        winHeight = $(window).height(),
    10        top = el.height() + el.offset().top + offset;
    11  
    12    // iScrollInstance.y为负值
    13    if (top - iScrollInstance.y > winHeight) {
    14       iScrollInstance.scrollTo(0, winHeight - top + iScrollInstance.y, 0);
    15    }
    16  
    17    // iOS7下聚焦键盘出现后,输入框没聚焦,这里设置下
    18    _ios7 && focusElement.focus();
    19 }

    说到iOS7,还有一个地方比较怪异,当点击输入框,键盘会出现,但是输入框没有聚焦。需要手动再点击一次。初步排查是iScroll4的问题,但没搞懂是哪出问题了,所以iKeyboardScroll4里对这些情况做了处理,暂时解决了这一问题。

    移动侧WebApp坑还是比较多,需要不断的积累经验才行啊~

  • 相关阅读:
    Android 一个app启动另一个app
    Android 电池电量进度条,上下滚动图片的进度条(battery)
    Android 返回键双击退出程序
    Failed to load or instantiate
    GNUstep 快捷键编译
    Android 文件夹命名规范 国际化资源
    mac 安装protobuf,并编译为java,c++,python
    Android 贝塞尔曲线 折线图
    android 制作自定义标题栏
    Gson
  • 原文地址:https://www.cnblogs.com/mrxia/p/3865519.html
Copyright © 2011-2022 走看看