Mobile web keyboard problem, IOS and Android input/textarea compatibility

Foreword: In mobile web development, the input/textarea input boxes of Android and IOS are different in calling the keyboard: the Android keyboard covers the bottom of the page; the IOS keyboard pushes the entire page to the top. Both implementations will cause some small problems on the page on the real machine. The main function of this article is to include such problems (you are also welcome to provide various problems or better solutions or point out the errors in this article, and encourage each other), I will continue to update it one after another. Here is a summary of what you have encountered or encountered by people around you, so that you or the people who use it can turn it over and look at it when you need it.

1. IOS machine

(1) Problem description:

In IOS 6s mobile phones, when the focus is obtained, the keyboard will push the entire page to the top . After the input is completed, the keyboard is retracted but the page remains in the state where the keyboard is pulled up, as shown in the following figure:

(2) Solution:

0. Determine whether it is an IOS machine

//判断是否是安卓还是ios
isAndroid() {
    let u = navigator.userAgent;
    let isAndroid = u.indexOf('Android') > -1 || u.indexOf('Linux') > -1; //android终端或者uc浏览器
    let isiOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/); //ios终端
    return isAndroid === true;
}

1. When the input is completed (the input box loses focus onblur), force the page to the top

//IOS 6s键盘收回
blurAddr() {
    if (isAndroid()) return;
    window.scroll(0, 0);//失焦后强制让页面归位
}

shortcoming:

When there is a lot of input content on the page and a scroll bar appears on the page, the page will be put to the top immediately after the previous input is completed. If you want to continue to input other content, you need to manually slide down to find the input box and enter again

Improve:

//IOS 6s键盘收回
blurAddr() {
    if (isAndroid()) return;
   setTimeout(() => {
                        var scrollHeight = document.documentElement.scrollTop || document.body.scrollTop || 0;//当失去焦点时,获取网页卷去距离
                        window.scrollTo(0, Math.max(scrollHeight - 1, 0));//强制重置滚动位置
                    },100);
}

2. Android machine

(1) Problem description:

When the focus is obtained, the keyboard will come out directly from the bottom and cover the upper layer of the page. If your input box is just at the bottom of the page, it will be blocked by the pop-up keyboard, and it cannot be swiped up to display it, as shown in the following figure:

(2) Solutions:

1. Make it swipe up to show:

The " page root node " sets the style style:

<section id="root" style="height:100%;overflow:auto;">
html代码布局
...
这里用textarea举例  input也是同样的
<textarea onfocus="onFocusAddr()"></textarea>
</section>

2. When the input box gets the focus, let the page scroll to the bottom:

//安卓键盘遮挡输入
onFocusAddr() {
    if (!isAndroid()) return;//判断是否是安卓机
    setTimeout(() => {
        let div = document.getElementById("root");//获取根节点
        div.scrollTop = div.scrollHeight;//滚动条至底(这里没有写的很严谨,需要减去输入框自身高offsetHeight,效果都一样)
    }, 500);//键盘拉起的延迟时间
}

shortcoming:

Obviously, this method is not universal, it needs to bind id to the DOM node, and it is troublesome to reuse

Improve:

//安卓键盘遮挡输入
onFocusAddr() {
    if (!isAndroid()) return;//判断是否是安卓机
    window.addEventListener('resize',()=>{
        setTimeout(() => { document.activeElement.scrollIntoViewIfNeeded();
//document.activeElement:文档中当前获得焦点的元素。scrollIntoViewIfNeeded():如果元素不在可见区将其滚动到浏览器窗口的可见区域,负责不动,scrollIntoView()的变体。 }, 0);//键盘拉起的延迟时间
    })
}

(3) The problem is solved, and the effect is as follows:

This is a native solution. It is recommended to improve it in combination with the framework you use, such as: angularJs, the vue framework can be encapsulated into instructions, which are more convenient to use, such as:

In vue:

directive.js:

import tools from '../../common/utils/tools';

function directives(Vue) {
//form表单输入键盘和滚动问题的兼容性处理
    Vue.directive('compatible', (el, binding) => {
        el.onfocus = () => {
            //安卓获得焦点时键盘遮挡输入
            if (!tools.isAndroid()) return;//判断是否是安卓机
            window.addEventListener('resize', () => {
                setTimeout(() => {
                    el.scrollIntoViewIfNeeded();
                    //document.activeElement:文档中当前获得焦点的元素。
                    //scrollIntoViewIfNeeded():如果元素不在可见区将其滚动到浏览器窗口的可见区域,负责不动,scrollIntoView()的变体。
                }, 0);//键盘拉起的延迟时间
            })
        };
        el.onblur = () => {
            //IOS 6s键盘收回时强制置顶
            if (tools.isAndroid()) return;
            setTimeout(() => {
                //当失去焦点时,获取网页卷去距离
                var scrollHeight = document.documentElement.scrollTop || document.body.scrollTop || 0;
                //强制重置滚动位置
                window.scrollTo(0, Math.max(scrollHeight - 1, 0));
            } ,100);
        };
    });
//禁止输入表情
    Vue.directive('no-emoji', (el, binding) => {
        // eslint-disable-next-line no-useless-escape
        var regStr = /[\uD83C|\uD83D|\uD83E][\uDC00-\uDFFF][\u200D|\uFE0F]|[\uD83C|\uD83D|\uD83E][\uDC00-\uDFFF]|[0-9|*|#]\uFE0F\u20E3|[0-9|#]\u20E3|[\u203C-\u3299]\uFE0F\u200D|[\u203C-\u3299]\uFE0F|[\u2122-\u2B55]|\u303D|[\A9|\AE]\u3030|\uA9|\uAE|\u3030/ig;
        if (regStr.test(el.value)) {
            el.value = (el.value.replace(regStr, '')).trim();
        }
        el.focus();
    });
}

export default directives;

main.js:

​​​​​​​import directive from './directive/directive';
//全局引用
Vue.use(directive);

form.vue:

<input type="text"
       maxlength="11"
       placeholder="请输入手机号"
       v-compatible
       v-no-emoji 
       v-model="submitInfo.phone"
>

ng中:

directive.js:

angular.module("ngDirective", ["service"])
    //IOS 6s键盘收回时强制置顶
    .directive("toScrollTop", () => {
        return {
            controller: ["$scope", "$element", ($scope, $element) => {
                $element.bind("blur", (event) => {
                    if (comService.isAndroid()) {
                        setTimeout(() => {
                            var scrollHeight = document.documentElement.scrollTop || document.body.scrollTop || 0;
                            window.scrollTo(0, Math.max(scrollHeight - 1, 0));
                        }, 100);
                    }
                });
            }
        };
    }])
    //安卓获得焦点时键盘遮挡输入
    .directive("keyboardDiscover", ["comService", (comService) => {
        return {
            controller: ["$scope", "$element", ($scope, $element) => {
                $element.bind("focus", (event) => {
                    if (comService.isAndroid()) {
                       window.addEventListener('resize', () => { setTimeout(() => { $element.scrollIntoViewIfNeeded(); }, 0);//键盘拉起的延迟时间 });
                    }
                });
            }]
        };
    }]); 

app.js:

​​​​​​​import directive from './directive/ngDirective.js';
//全局注入
angular.module("app", [
     ...
     "ngDirective"
])

form.html:

<input type="text"
       placeholder="请输入手机号"
       to-scroll-top
       keyboard-discover
       ng-model="submitInfo.phone"
       maxlength="11">

 

 

{{o.name}}
{{m.name}}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324136504&siteId=291194637
Recommended