移动端关于软键盘的两个问题

1,953 阅读2分钟

移动端关于软键盘的问题主要有两个:

  • 软键盘的弹出导致页面的布局错乱的问题
  • 某些表单页面,需要一进入页面就获取焦点,并弹出软键盘

先来看下第一个问题,如下图所示

在这个页面中,正常情况下,二维码授权是绝对定位在页面底部的,软键盘弹起时,由于页面收缩,导致绝对定位在键盘上方。

网上的解决方案中,有在软键盘弹出时,将绝对定位改为相对定位,经测试,这种方法,不行,因为页面html元素和body元素的高度设置都为100%,正因如此,软键盘弹起时,页面才会被压缩

还有一种解决方案,此种方案针对安卓机型,监听页面中window.resize事件,这种方法亲测有效, 代码如下

const htmlHeight = window.getComputedStyle(document.querySelector('html'), null).getPropertyValue('height').slice(0, -2);
window.onresize = () => {
    //在这里判断页面的高度与初始高度的差距,若大于某一阈值,则判定为软键盘弹起
    const thisHeight = window.getComputedStyle(document.querySelector('html'), null).getPropertyValue('height').slice(0, -2);
    if(htmlHeight - thisHeight > 140) {
        //判断为软键盘弹起,将元素隐藏掉
    }
}

其中,获取页面高度的方法不唯一。 还有针对Ios的方案,不过这种方案没有验证过,存疑,监听input元素的focus,blur事件,做显示和隐藏的判断。

再看下第二个问题,一进入页面就获取焦点,并自动弹出软键盘。

关于这个问题,网上的说法也是非常多,autofocusel.click()el.focus(),网上的说法是,这些方法兼容性不好,但是经我验证,这些方法都不起作用!!(难道是我手机太差)

只有一种方案可行

软键盘的弹起,只对用户操作的事件有效

意思就是不能直接触发focus事件,不过可以给其他元素绑定一个click事件,在回调函数中去触发focus事件,不过有一点,在页面刚刚加载完成时,可能也不会生效,因此,需要找到一个能使软键盘弹出的时间节点,依靠setTimeout去进行延迟执行,代码如下

<html>
    <body>
        <label for="username"></label>
        <input id="username" />
    </body>
    <script>
        document.querySelector('label').onclick = () => {
            document.querySelector('#username').focus();
        }
        setTimeout(() => {
            document.querySelector('label').click();
        }, 1000)
    </script>
</html>