问题
ios设备:点击input,软键盘弹出,页面整体向上偏移
需求
当软键盘弹起,input改变位置并始终贴着软键盘,整体页面不上移动
解决
页面采用flex布局
<div class="flex"> <div class="box"> <div class="head"></div> //标题区 <div class="body"></div> //内容滚动区 <div class="foot"></div> //输入区 </div> </div>
涉及内置API,返回一个DOMRect对象,包含left
、top
、right
、bottom
、x
、y
、width
和 height元素。
document.getBoundingClientRect()
getBoundingClientRect()是相对浏览器而言的,因此使用与整体页面偏移的情况。
offset()也是可以计算偏移量,但其是相对于父元素,因此在此处不适用
setTimeout(() => { let flex = document.querySelector('.flex') //页面向上偏移量 let changeHeight = flex.getBoundingClientRect().top //flex高度 let flexHeight =flex.offsetHeight //改变flex-div的height flex.style.height = parseInt(flexHeight + changeHeight) + 'px' } }, 100)
因为要考虑软键盘弹出是动画需要时间,所以设置定时器来暂缓代码。为了让效果看起来连贯,定时设置为100ms,而下面让页面回滚定时为101ms。
遗留问题
当软键盘弹起,页面高度减少,但是在页面和软键盘之间会遗留一片空白区域,不知道是什么原因,只能通过设置页面滚动来返回初始位置
setTimeout(() => { window.scroll(0, 0) }, 101)
源码
项目是用vue写,并且设定了在某种条件下才处理软键盘
只有ios才要处理,增加判断打开页面设备是否为ios
setFlexHeight() { //判断是否为ios设备,只有ios设备有这样的情况 const user = navigator.userAgent let isIos = !!user.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/); //ios终端 if (isIos) { setTimeout(() => { if (this.contentList.length >= 3) this.flexHeight = '100%' else { //页面向上偏移量 let changeHeight = this.$refs.flex.getBoundingClientRect().top //flex高度 let flexHeight = this.$refs.flex.offsetHeight //改变flex-div的height this.flexHeight = parseInt(flexHeight + changeHeight) + 'px' } }, 100) //因为软键盘弹起页面缩短,导致页面和软键盘之间留白 //重新让页面回到底部 if (this.contentList.length < 3) { setTimeout(() => { window.scroll(0, 0) }, 101) } } }