问题

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对象,包含lefttoprightbottomxywidthheight元素。

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)          }        }      }