移动端web页面软键盘遮挡相关调研

2,079 阅读3分钟

一、先说结论

  1. 移动端软键盘弹起据我所知主要有2种,一种是现在绝大部分机型中浏览器默认设置的,弹起输入法,将整个web页面部分顶上去,整个页面内容被顶上去;另一种是一些旧版本的浏览器设置的,软键盘出现,只是一个类似绝对定位的遮盖,页面内容被遮盖;这些都能在App的webview中进行设置;
  2. 发生输入法弹起遮盖页面内容,如果是一种顶上去的情况,设置滚动条高度,滚到指定位置即可,如果是第二种设置,纯js没有好的办法实现;如果是自家的app,不推荐第二种软键盘设置;
  3. ios下如果切成搜狗输入法,在safari等浏览器下,第一次进入浏览器(与刷新无关)唤起输入法,大概率会是出现类似第二种绝对定位的情况,之后唤起输入法正常;切成默认输入法,一直正常;
  4. 有解决办法。

二、情况与对应处理

  1. 情景:移动端网页内,软键盘弹起遮盖掉输入框;

    处理:需要通过scrollTop等方法,将滚动条聚焦到需要显示的位置;

  2. 情景:在开发过程中,因为输入框在页面底部,发现在app中webview内,唤起输入法,输入框会被遮盖掉;

    原因:app webview设置的软键盘弹起方式未将页面顶起;

    分析:

    • 通过比较网页在浏览器下显示正常,但是在app内被遮盖;
    • 然后检查在app内弹起输入法后的,网页高度变化,与其他浏览器进行比较,发现App内可见高度(innerHeight)等变化不大,基本确定是软键盘设置方式问题;(检查移动端网页内元素情况,推荐 spy-debugger
    • 将淘宝,阿里云的咨询页面,放到app内访问,同样会被遮盖;

    处理:App将软键盘弹起方式设置为第一种将整个页面顶上去;

  3. 情景: 低版本浏览器(android 4.4)的软键盘弹起方式遮盖输入框;

    分析:

    • 高版本浏览器下显示正常;
    • 通过弹起输入框后,可见高度等进行比较,发现是第二种类似绝对定位的覆盖,没有顶起来;
    • 发现淘宝,阿里云的咨询页面在低版本浏览器下也有这个问题

    处理:版本太低不做兼容;

  4. 情景:ios下默认设置搜狗输入法,每次杀掉app进程后,第一次进入app,第一次唤起输入法,底部的输入框会被搜狗输入法遮盖掉,第二次唤起输入法后,页面被顶起,显示变为正常;只有设置了搜狗输入法后,第一次进app第一次唤起输入法会遮盖,默认输入法一直是正常的;

    分析:

    • 通过唤起搜狗输入法后的高度比较,发现第一次唤起此时软键盘弹出方式也是类似第二种绝对定位的弹出,之后唤起软键盘变为第一种顶起的实现,显示正常;
    • app是设置的第一种顶起来页面内容的软键盘弹起;
    • 阿里云的咨询页面在此种操作下,也会被遮盖;

    处理: 通过检测是ios系统,在点击键盘时,设置一定延时,然后调用scrollTop 和 scrollIntoView,在uc浏览器下另外寻新增处理,代码如下:

    /**
     * @description: 在ios下进行处理,在ios + uc下,新增一次处理
     * @param {*} target 需要处理键盘覆盖的元素
     * @param {*} sleep 设置的延时
     * @return {*}
     */
    function keyboardAndIntoView(target, sleep = 500) {
        if (judgeSystem() === "ios") {
            setTimeout(() => {
                targetGoToView(target)
                if (judgeBorwser() === "uc") {
                    setTimeout(() => {
                        that.targetGoToView(target)
                    }, 200)
                }
            }, sleep)
        }
    }
    
    /**
     * @description: 将元素滚动到底部,不被软键盘遮盖
     * @param {*} target 需要处理键盘覆盖的元素
     * @return {*}
     */
    function targetGoToView(target) {
        document.body.scrollTop = document.body.scrollHeight + 100;
        target.scrollIntoView(true)
    }