`
liuguofeng
  • 浏览: 435152 次
  • 性别: Icon_minigender_1
  • 来自: 成都
社区版块
存档分类
最新评论

iScroll4下表单元素聚焦及键盘的异常问题

 
阅读更多

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

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

 

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

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

 

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

 

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

function detect() {
        // 不等表示翻屏
        if (_landscape != _landscape2) {
            // 屏幕翻转且翻转前键盘处于显示状态时,交换宽高
            if (_display) {
                var tmpWidth = _initWinWidth;
                _initWinWidth = _initWinHeight;
                _initWinHeight = tmpWidth;
            } else {
                _initWinWidth = $(window).width();
                _initWinHeight = $(window).height();
            }
        }

        var h = $(window).height();
        _display = _activeElement !== null && _initWinHeight > h;

        $.each(_callback, function(k, v) {
            v.apply(null, [_display, _activeElement]);
        });
        _landscape = _landscape2;
    }

 

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

 

$(window).on('orientationchange', function(e) {
        _landscape2 = !!(window.orientation & 2);

        // ios下可以直接取宽高,且ios下onresize似乎比orientationchange先触发,因此setTimeout的时机不好掌控
        _ios7 && detect();
    }).on('resize', function(e) {
        // ios下onresize似乎比orientationchange先触发,因此setTimeout的时机不好掌控
        // 对于ios,翻屏时统一通过orientationchange进行处理,非翻屏时统一使用onresize
        // ios下,onresize后若宽度不相同证明翻屏了,此时使用orientationchange来进行处理
        // Android不变,使用onresize处理
        if (_ios7 
            && (_landscape != _landscape2 // 此判断是为了防止orientationchange先于onresize触发
                || $(window).width() != _initWinWidth)) {
            return;
        }

        _timer && clearTimeout(_timer);
        // Android下orientationchange之后获取window值会延时
        _timer = setTimeout(detect, 200);
    });

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

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

 

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

// 聚焦且键盘显示时,修正输入框位置
// iOS6会自动定位到输入框,但还是需要refresh位置
// iOS7不会自动定位到输入框,表现跟Android类似
if ((!$.os.ios || _ios7) 
   && display && focusElement) {
   offset = $.type(offset) == 'number' ? offset : 5;

   var el = $(focusElement),
       winHeight = $(window).height(),
       top = el.height() + el.offset().top + offset;

   // iScrollInstance.y为负值
   if (top - iScrollInstance.y > winHeight) {
      iScrollInstance.scrollTo(0, winHeight - top + iScrollInstance.y, 0);
   }

   // iOS7下聚焦键盘出现后,输入框没聚焦,这里设置下
   _ios7 && focusElement.focus();
}

 

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

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

分享到:
评论

相关推荐

    iscroll4

    iscroll4

    iScroll4框架

    iScroll 4 这个版本完全重写了iScroll这个框架的原始代码。这个项目的产生完全是因为移动版webkit浏览器(诸如iPhone,iPad,Android 这些系统上广泛使用) 提供了一种本地化的方式来对一个限定了高度和宽度的...

    iscroll4.js

    html5页面支持上拉刷新下拉加载更多数据的实现,关于实现可以看看这篇文章:https://blog.csdn.net/u012962759/article/details/85329854

    原生 iscroll-4

    原生 iscroll-4

    iscroll-4.rar

    iscroll.js是Matteo Spinelli开发的一个js文件,使用原生js...旨在解决移动webkit系浏览器的区域滚动问题,兼容mobile safari、android默认浏览器、safari、chrome、firefox5+、opera11+、IE9+及其他webkit核心浏览器。

    iScroll下拉刷新上滑加载

    使用经典插件iScroll4稍作封装,采用ajax请求数据,实现移动端列表页的功能; 1.下拉刷新当前列表页数据; 2.上滑加载更多列表数据; iScroll4简介: iScroll 4 这个版本完全重写了iScroll这个框架的原始代码...

    iscroll4例子

    iscroll4 demo例子。可以帮助你快速开发手机列表

    iScroll框架

    iScroll 4 这个版本完全重写了iScroll这个框架的原始代码。这个项目的产生完全是因为移动版webkit浏览器(诸如iPhone,iPad,Android这些系统上广泛使用)提供了一种本地化的方式来对一个限定了高度和宽度的元素的...

    iscroll5 refresh 及iscroll4刷新功能

    iScroll-5拉动刷新(pull-to-refresh) 根据iscroll4代码改写结构一样。

    iScroll 5下拉刷新

    iScroll 5下拉刷新。 iScroll 5 更新之后的pull-to-refresh的demo没了,无奈,google下一个国外程序员写的上下拉刷新,自己精简了下,只保留了下拉刷新。

    H5使用iscroll-4模拟手机app下拉刷新功能实现demo

    1. 使用iscroll-4 前端技术 2 .H5模拟手机app下拉刷新

    iscroll5上拉下拉实例完整demo

    iscroll5上拉下拉实例完整demo,iscroll5刚出来的时候自己写的demo,本人已经改行无意间上来看了下,把积分调整低

    jquery iscroll下拉插件

    jquery iscroll下拉插件

    iscroll所用到的js文件

    包含iscroll.js、iscroll-infinite.js、iscroll-lite.js、iscroll-probe.js、iscroll-zoom.js

    iscroll5 滑动 滚动

    iscroll5 滑动 滚动 最新资讯

    iscroll.js

    iscroll.js

Global site tag (gtag.js) - Google Analytics