input框移动端中键盘收起改变页面布局出现空白的情况

解决position:fixed受虚拟键盘的影响

1. 不适用fixed定位,使用替代方案(推荐的方法):

a方案:使用overflow-y:scroll;+position:absolute;
b方案:使用overflow-y:scroll;+flex布局;

其中,a方案内容区域的高度通过js控制;b方案内容区域的高度通过flex布局自动排版;

2. 根据输入框获取焦点与失去焦点事件切换fixed定位与static定位

问题源头可能是:移动端虚拟键盘出现的条件是:文本框(文本类)获得焦点

弹出键盘后原先定位与底部的东西会被虚拟键盘顶上去,样式错乱!

首先我们会想到监听focus和blur事件,但是会有bug,虚拟键盘有自带的收起键盘,这样输入框还是聚焦事件,并没有触发blur事件。所以会导致失效的。

解决办法

我们可以换一个思路。监听改变浏览器窗口高度的时候去触发事件。

1
2
3
4
5
6
7
8
windowInnerHeight = window.innerHeight; //获取当前浏览器窗口高度
$(window).resize(function(){
if(window.innerHeight < windowInnerHeight){
$('.footer').removeClass('footerss');
}else{
$('.footer').addClass('footerss');
}
});


解决输入框input获取焦点得时,虚拟键盘会把fixed元素顶上去(次现在在部分安卓上能发现)

1
2
3
4
5
6
7
$('#phone').bind('focus',function(){
$('.bottom_fix').css('position','static');
//或者$('#viewport').height($(window).height()+'px');
}).bind('blur',function(){
$('.bottom_fix').css({'position':'fixed','bottom':'0'});
//或者$('#viewport').height('auto');
});

解决屏幕旋转也会出现以上问题

1
2
3
4
5
6
7
$(document).bind('orientationchange',function(){
if(window.orientation==90 || window.orientation==-90){
$('.bottom_fix').css('position','static');
}else{
$('.bottom_fix').css({'position':'fixed','bottom':'0'});
}
});

通过resize() 方法触发 resize 事件,或规定当发生 resize 事件时运行的函数。

1
2
3
4
5
6
7
8
9
10
11

var windheight = $(window).height(); /*未唤起键盘时当前窗口高度*/

$(window).resize(function(){
var docheight = $(window).height(); /*唤起键盘时当前窗口高度*/
if(docheight < windheight){ /*当唤起键盘高度小于未唤起键盘高度时执行*/
$(".submit").css("position","static");
}else{
$(".submit").css("position","fixed");
}
});

h5 ios中软键盘弹起后 fixed定位失效

position: fixed;在ios手机中会存在一个失效情况:
如果页面有输入框存在,点击输入框软键盘弹起后会发生一个现象:

  1. 针对当前内容高度小于屏幕高度时:
    上下滑动页面时候,发现之前fixed定位在顶部的元素会跟随页面滚动,变成了absolute定位的效果。
  2. 针对当前内容高度大于屏幕高度时:
    之前fixed定位在顶部的View不见了,下滑往上翻页面后,就会看那个fixed定位的元素错落在页面中,但并不是在最顶部。

综上可以看出,ios浏览器是针对fixed定位的元素作了处理,不再是之前定位效果,变成了absolute定位的效果但并不是absolute,但可以理解为top:对应为当前body的scrollTop值。

那么该怎么解决这个问题呢?

在这里我是比较倾向于遵循ios浏览器处理fixed元素的初衷,浏览器去处理fixed元素应该是有它考虑的地方,退一步说其实也没有必要在这个情况下强制显示顶部元素,这时候用户的重点在于输入。

这里给出的方案就是:在软键盘弹起后,直接把fixed的元素变成absolute的,不需要浏览器自己去做处理,待键盘收起后再恢复成fixed。

1
2
3
4
5
6
7
8
9
10
11
//以下代码环境是在React中
document.body.addEventListener('focusin', () => {
//软键盘弹出的事件处理
let scrollTop = document.body.scrollTop || document.documentElement.scrollTop;
//注只针对ios 、处在滚动中位置时
isIphone() && scrollTop > 0 && this.setState({ className: 'postion-absolute' })
})
document.body.addEventListener('focusout', () => {
//软键盘收起的事件处理
isIphone() && this.setState({ className: '' })
})

h5 安卓 键盘弹起界面适配 修改webview高度

存在按钮使用绝对定位去实现。然后再到真机上去测试时,会发现ios手机是蛮正常的体验,软键盘会直接从底部覆盖最下面的按钮的,那是因为ios上的键盘是处在窗口的最上层,直接覆盖窗口不会挤压窗口;

首先还是从源头上看,针对安卓系统来说,软键盘弹起的方式是很有多种的常用的是这2种android:windowSoftInputMode=”adjustPan|adjustResize”

  1. “adjustResize”
    该Activity主窗口总是被调整屏幕的大小以便留出软键盘的空间,会调用onSizeChanged方法
  2. “adjustPan”
    该Activity主窗口并不调整屏幕的大小以便留出软键盘的空间。相反,当前窗口的内容将自动移动以便当前焦点 不被键盘覆盖和用户能总是看到输入内容的部分。不会调用onSizeChanged方法

综上所述安卓会发生这个现象是因为原窗口为了留出软键盘的空间,高度发生了改变,绝对定位在底部的按钮就会被挤压,给人的假象就是被键盘顶起。既然我们知道了原因出在了原窗口高度发生了改变,那就有可做文章的地方,请看下面的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
//获取原窗口的高度
var originalHeight=document.documentElement.clientHeight ||document.body.clientHeight;
window.onresize=function(){
//键盘弹起与隐藏都会引起窗口的高度发生变化
var resizeHeight=document.documentElement.clientHeight || document.body.clientHeight;
//1. 从app自身的Webview高度方面去考虑
if(resizeHeight-0<originalHeight-0){ // resizeHeight<originalHeight证明窗口被挤压了
plus.webview.currentWebview().setStyle({
height:originalHeight //强设置为原高度
});
}
// 2. 从h5自身角度去解决
if(resizeHeight-0<originalHeight-0){ // resizeHeight<originalHeight证明窗口被挤压了
可以去操作dom 进行隐藏按钮 // xxx.style.display='none';
//隐藏的手段就有很多了 可以z-index为负数、opacity透明度等等
}else{
还原按钮的显示 // xxx.style.display='';
}
}

h5 移动端 监听软键盘弹起、收起

在adnroid中如何监听软键盘的弹起与收起,是利用的窗口的高度发生变化
window.onresize事件来做突破点的,但是ios中软键盘的弹起收起并不触发window.onresize事件。

  • 总结:
  1. 在ios中软键盘弹起时,仅会引起$(‘body’).scrollTop值改变,但是我们可以通过输入框的获取焦点情况来做判断,但也只能在ios中采用这个方案,因为在android中存在主动收起键盘后,但输入框并没有失焦,而ios中键盘收起后就会失焦;
  2. 在android中软键盘弹起或收起时,会改变window的高度,因此监听window的onresize事件;
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
//一、Android
//获取原窗口的高度
var originalHeight=document.documentElement.clientHeight ||document.body.clientHeight;
window.onresize=function(){
//键盘弹起与隐藏都会引起窗口的高度发生变化
var resizeHeight=document.documentElement.clientHeight || document.body.clientHeight;
if(resizeHeight-0<originalHeight-0){
//当软键盘弹起,在此处操作
}else{
//当软键盘收起,在此处操作
}
}
//二、ios
//focusin和focusout支持冒泡,对应focus和blur, 使用focusin和focusout的原因是focusin和focusout可以冒泡,focus和blur不会冒泡,这样就可以使用事件代理,处理多个输入框存在的情况。
document.body.addEventListener('focusin', () => {
//软键盘弹出的事件处理
if(isIphone()){

}
})
document.body.addEventListener('focusout', () => {
//软键盘收起的事件处理
if(isIphone()){

}
})

使用fiexd定位input框可以被在ios系统中唤起键盘跟着推上去

当键盘出来的时候,红色的div不见了。然后我就查了一下,是ios里面的就有这个bug。我就试了很多网上的方法都是不行。发现只有ios这样,安卓没有。我就做了个兼容判断

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//评论输入框
var interval
$("#shuruk").focus(function () {
if (/iphone|ipad|ipod/.test(ua)) {
interval = setInterval(function() {
document.body.scrollTop = document.body.scrollHeight
}, 100)
} else if (/android/.test(ua)) {

}

})

//消息框失去焦点
$('#shuruk').blur(function(){
clearInterval(interval);
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
mounted () {
this.clientHeight = document.documentElement.clientHeight;
const that = this;
// 安卓手机键盘吊起挡住输入框

window.onresize = function() {

if(document.documentElement.clientHeight < that.clientHeight) {
// scrollVal为负值
let scrollVal = document.documentElement.clientHeight-that.clientHeight;
$(".alert-main").css("marginTop",scrollVal);
$(".bottom-create").hide();
}else {
$(".alert-main").css("marginTop",0);
$(".bottom-create").show();
}

};
},

今天这个bug 遇到了新问题,同样的华为手机上,当从别的路由吊起输入键盘的时候回到当前路由,

document.documentElement.clientHeight就变成了减去输入键盘高度的值,

这时需要在页面第一次加载将document.documentElement.clientHeight记录到store中,store中的值不会因为页面重新渲染而改变。

×

纯属好玩

扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

文章目录
  1. 1. 解决position:fixed受虚拟键盘的影响
    1. 1.1. 1. 不适用fixed定位,使用替代方案(推荐的方法):
    2. 1.2. 2. 根据输入框获取焦点与失去焦点事件切换fixed定位与static定位
  2. 2. 问题源头可能是:移动端虚拟键盘出现的条件是:文本框(文本类)获得焦点
  3. 3. 解决输入框input获取焦点得时,虚拟键盘会把fixed元素顶上去(次现在在部分安卓上能发现)
  4. 4. 解决屏幕旋转也会出现以上问题
    1. 4.1. 通过resize() 方法触发 resize 事件,或规定当发生 resize 事件时运行的函数。
  5. 5. h5 ios中软键盘弹起后 fixed定位失效
  6. 6. h5 安卓 键盘弹起界面适配 修改webview高度
  7. 7. h5 移动端 监听软键盘弹起、收起
  8. 8. 使用fiexd定位input框可以被在ios系统中唤起键盘跟着推上去
,