解决ios设备软键盘弹出导致页面整体被顶起

  • Post category:JavaScript

问题

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对象,包含lefttoprightbottomxywidth 和 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)
          }
        }
      }