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坑还是比较多,需要不断的积累经验才行啊~

  • 相关阅读:
    hdu 1199 Color the Ball 离散线段树
    poj 2623 Sequence Median 堆的灵活运用
    hdu 2251 Dungeon Master bfs
    HDU 1166 敌兵布阵 线段树
    UVALive 4426 Blast the Enemy! 计算几何求重心
    UVALive 4425 Another Brick in the Wall 暴力
    UVALive 4423 String LD 暴力
    UVALive 4872 Underground Cables 最小生成树
    UVALive 4870 Roller Coaster 01背包
    UVALive 4869 Profits DP
  • 原文地址:https://www.cnblogs.com/mrxia/p/3865519.html
Copyright © 2011-2022 走看看