移动开发h5表单键盘弹出问题

最近在做移动端开发,每过一段时间,发现又出现新的兼容问题,这次也不例外。

ios手机

之前ios手机是没有问题的,昨天测试的时候发现键盘弹出不会有遮挡input表单的问题,但是输入完成,键盘收回后发现,页面会有一个空白位置没有收回
键盘收回.jpeg

键盘弹出.jpeg
可以在失去input焦点blur的时候用scrollTo做个处理还原页面的位置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
function getPlat() {
let u = navigator.userAgent;
let isAndroid = u.indexOf('Android') > -1 || u.indexOf('Adr') > -1; //判断是否是 android终端
let isIOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/); //判断是否是 iOS终端
if (isAndroid) {
return 'Android';
} else if (isIOS) {
return 'IOS';
} else {
return 'PC';
}
}
if (getPlat() === 'IOS') {
setTimeout(() => {
const scrollHeight = document.documentElement.scrollTop || document.body.scrollTop || 0;
window.scrollTo(0, Math.max(scrollHeight - 1, 0));
}, 0);
}

Android手机(测试机有oppo、华为、三星、锤子)

但是在Android 手机中就没有这么容易了,测试发现,安卓手机中如果不做任何处理,弹出的键盘会遮盖输入框,但是键盘弹出后手动滚动页面,收回键盘,在聚焦弹出键盘就会定位到上次滚动的地方。其实这样也还好,但是测试要求想要自动展示到键盘上方。所以我需要做些兼容处理
经检测有几种解决办法:
一、修改输入登录模块的定位用fixed、会跟着键盘一起动,可以在聚焦失焦给样式做些处理,但是会麻烦一些
二、scrollIntoView 与 scrollIntoViewIfNeeded API
可以在页面挂载完成mounted的时候做处理,统一对所有的input和textarea做处理

1
2
3
4
5
6
7
8
9
if ((/Android/gi).test(navigator.userAgent)) {
window.addEventListener('resize', function () {
if (document.activeElement.tagName == 'INPUT' || document.activeElement.tagName == 'TEXTAREA') {
window.setTimeout(function () {
document.activeElement.scrollIntoViewIfNeeded();
}, 0);
}
});
}

或者在input聚焦focus的时候做处理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
<template>
<input
v-model="codeValue"
type="text"
placeholder="请输入收到的验证码"
class="verify-input"
maxlength="6"
@focus="changefocus"
@blur.prevent="blur"
>
</template>
<script>
export default {
methods: {
blur(){
if (judgeClient() === 'IOS') {
setTimeout(() => {
const scrollHeight = document.documentElement.scrollTop || document.body.scrollTop || 0;
window.scrollTo(0, Math.max(scrollHeight - 1, 0));
}, 0);
}
},
changefocus() {
if (this.getPlat() === 'Android') {
setTimeout(() => {
el.target.scrollIntoViewIfNeeded(true);
el.target.scrollIntoView(true);
}, 200);
}
},
getPlat() {
let u = navigator.userAgent;
let isAndroid = u.indexOf('Android') > -1 || u.indexOf('Adr') > -1; //判断是否是 android终端
let isIOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/); //判断是否是 iOS终端
if (isAndroid) {
return 'Android';
} else if (isIOS) {
return 'IOS';
} else {
return 'PC';
}
}
}
}
</script>

安卓手机有延迟,有时生效,有时会失效,可能setTimeout设置的延迟事件不够,我设置100的时候还会经常没生效,但是设置200貌似就好很多