键盘弹起时遮挡页面内容
在一些聊天系统中,我们点击输入框,会自动调起系统键盘,从页面底部弹出,然后页面的内容会被自动顶上去,内容就不会被输入框遮挡
但是在一些系统中会存在有时会存在键盘弹起时,页面没有被完全顶上去,部分页面内容被弹起来的键盘遮挡住了,一般最底部的都是输入框,这时候输入框被遮挡了,那怎么完成内容输入的交互呢
安卓可以借助Element.scrollIntoView()来解决,让元素滚动到浏览器窗口的可视区内,第一个参数设为false,意思是元素的底端将和可视区的底端对齐,因为是键盘弹出后出现的问题,可以监听输入框的focus事件,但由于键盘弹出是有动画的,如果立即执行scrollIntoView(),有时输入框还是会被挡住,因此要加延时
ios中scrollIntoView()按道理也是可以用的,但是实际好像是无效的,针对这种情况,可以借助document.body.scrollTop,让元素的滚动位置为它的内容的高度,这样就可以将滚动条滚动到内容的底部位置,但是在ios 11.0~11.3这些系统下,scrollTop或者scrollIntoView是有bug的,所以排除一下
const ua = navigator.userAgent;
const ios = /iPad|iPhone|iPod/.test(ua);
const input = document.querySelector('#input');
input.addEventListener('focus', () => {
setTimeout(() => {
if(ios) {
if(!/OS 11_[0-3]\D/.test(ua)) {
document.body.scrollTop = document.body.scrollHeight;
}
} else {
input.scrollIntoView(false);
}
}, 300);
});
如果在ios中上面的方法解决不了,那么可以使用下面的方法:
这里需要操作的是window对象,而不是document对象
window.visualViewport
当前窗口的可视视口对象
在键盘弹起时,帮助页面滚动
原理:页面应滚动的高度(键盘的高度) = 键盘未弹起时的视口高度 - 键盘弹起时的视口高度
在实际操作中发现有以下几种场景存在问题,分别做了兼容兜底逻辑
- 键盘弹起后页面没有滚动
- 键盘弹起后页面滚动了,但是滚动不够,没有滚动到可视区的对应位置
- 发送一条消息之后,输入框弹起,页面没有滚动到可视区
focus() {
const initVisualViewportHeight = window.visualViewport && window.visualViewport.height;
this.focusTimer = setTimeout(() => {
if (window.visualViewport) {
const scrollHeight = (initVisualViewportHeight - window.visualViewport.height) || this.currentScrollY;
// 解决没有滚动的问题
if (window.scrollY === 0) {
window.scrollTo({
top: scrollHeight,
behavior: 'smooth',
});
}
// 解决正确计算了要滚动的高度,但是没有滚动到位的问题
this.secondScrollTimer = setTimeout(() => {
if (scrollHeight - window.scrollY > 10) {
window.scrollTo({
top: scrollHeight,
behavior: 'smooth',
});
}
}, 100);
// 解决发送消息后计算要滚动的距离不准确的问题
this.currentScrollY = scrollHeight;
}
}, 600);
}
// focus时用到的定时器,在blur的时候要清除
blur() {
this.secondScrollTimer && clearTimeout(this.secondScrollTimer);
this.focusTimer && clearTimeout(this.focusTimer);
},
键盘收起时页面内容没滚到底部
input.addEventListener('blur', () => {
document.body.scrollIntoView();
});