一、需求问题
在移动端开发的表单页面当中,在android
手机上,当点击表单页面的输入框以后,获取焦点,软键盘弹出,会覆盖住表单页面的输入框,会出现这样的问题。
二、需求分析
这种问题出现在android
手机上,当输入框在可视区域底部或者偏下的位置,输入框获取焦点弹出软键盘,软键盘覆盖表单页面中的输入框。这个也是android
手机经常遇到的问题。
-
第一种方法:我们可以在页面渲染完成后,通过JS动态获取屏幕可视区高度,同时屏幕旋转后,也需重新获取屏幕高度并赋值,并将其赋值到
bod
的height
,这样body
的高度一直都是屏幕的高度,当软键盘弹出后,会将body
向上推,这也是因为body
有了固定高度,不会再继承html
的自适应高度,使输入框置到可视区内。在vue
项目中,在created
钩子函数,页面初始化完成的时候,获取屏幕的可视化高度,并且将获得的可视化高度进行赋值就可以了。 -
第二种方法:我们可以借助元素的
scrollIntoViewIfNeeded()
方法,这个方法执行后如果当前元素在可视区中不可见,则会滚动浏览器窗口或容器元素,最终让它可见,如果当前元素在可视区中,这个方法就什么都不做。 -
第三种方法:我们可以利用捕获事件监听输入框等
focus
操作。 -
第四种方法:监听
resize
事件,然后定位到input
输入框,也可以理解为监听input
状态,屏幕滚动到input
,上下居中。
三、需求实现
1. 第一种方法的代码实现:
document.body.style.height = window.screen.availHeight +'px';
vue的实现:
created() {
// 获取.box的可视区域的高
let flexheight = document.documentElement.clientHeight;
// 在页面整体加载完毕时
window.onload = () => {
// 把获取到的高赋值给.box
document.getElementByclassName('box').style.height = `${flexheight}px`;
};
}
2. 第二种方法的代码实现:
window.addEventListener('resize', () => {
if (document.activeElement.tagName == 'INPUT') {
//延迟出现是因为有些 android 手机键盘出现的比较慢
window.setTimeout(() => {
document.activeElement.scrollIntoViewIfNeeded();
}, 100);
}
});
3. 第三种方法的代码实现:
var clientHeight = document.body.clientHeight;
//输入框焦点
var _focusElem = null;
//利用捕获事件监听输入框等focus动作
document.body.addEventListener("focus", function(e) {
_focusElem = e.target || e.srcElement;
}, true);
//因为存在软键盘显示而屏幕大小还没被改变,所以以窗体的屏幕显示大小改变为准
window.addEventListener("resize", function() {
if (_focusElem && document.body.clientHeight < clientHeight) {
//焦点元素滚动到可视范围的底部,false为底部,true为顶部
_focusElem.scrollIntoView(false);
}
});
4. 第四种方法的代码实现:
//监听input状态,屏幕滚动到input,上下居中
//在安卓手机上屏幕尺寸变化会产生resize事件,所以监听resize事件,然后定位到input框
window.addEventListener('resize', function () {
if(document.activeElement.tagName === 'INPUT'){
document.activeElement.scrollIntoView({behavior: "smooth"})
}
})