移动iOS端软键盘弹起空白和滚动穿透问题

在作h5移动端项目的时候,给用户一个十分友好的体验是很必要的。最近抽空整理了下移动端(iOS端)项目中常常碰到的两个问题vue

键盘弹起空白

在咱们点击input等弹出手机键盘,在点击完成后常常会在底部出现跟键盘同大小的空白,可是当咱们滚动下页面发现又好了,这个在iOS端能够说很常见的问题了(应该是布局定位形成的,具体缘由没仔细研究),解决方法就是在结束输入的时候控制滚动条偏移下就好。
下面是相关代码:web

.inTouch {
  -webkit-overflow-scrolling: auto;
}
.noTouch {
  -webkit-overflow-scrolling: touch;
}
import Vue from 'vue'
Vue.directive('resetPage', {
  inserted (el) {
    document.body.addEventListener('focusin', () => {
      if (/(iPhone|iPad|iPod|iOS)/i.test(navigator.userAgent)) {
        // 软键盘收起的事件处理
        setTimeout(() => {
          document.getElementsByTagName('body')[0].className = 'inTouch'
        }, 100)
      }
    })
    document.body.addEventListener('focusout', () => {
      if (/(iPhone|iPad|iPod|iOS)/i.test(navigator.userAgent)) {
        // 软键盘收起的事件处理
        setTimeout(() => {
          const scrollHeight = document.documentElement.scrollTop || document.body.scrollTop || 0
          window.scrollTo(0, Math.max(scrollHeight - 1, 0))
          document.getElementsByTagName('body')[0].className = 'noTouch'
        }, 100)
      }
    })
  }
})

在iOS端,当元素得到焦点的时候,咱们把-webkit-overflow-scrolling的值设为auto,防止滚动穿透。当元素失去焦点的时候,咱们把值恢复为touch,这样页面的滚动效果不会丢失,同时咱们控制滚动条偏移了1像素,解决软键盘弹起空白的问题。
关于我设置的-webkit-overflow-scrolling属性可多说两句:布局

// -webkit-overflow-scrolling这个样式相信你们都很熟悉了,有auto、touch两个可选值
// auto:使用普通滚动, 当手指从触摸屏上移开,滚动会当即中止。
// touch:使用具备回弹效果的滚动, 当手指从触摸屏上移开,内容会继续保持一段时间的滚动效果。继续滚动的速度和持续的时间和滚动手势的强烈程度成正比。同时也会建立一个新的堆栈上下文。
// 为了增长滚动的流畅性,作iOS移动端适配的时候都会增长这个样式适配的
-webkit-overflow-scrolling: touch;

查看兼容性的过后素咱们发现只在iOS端可用,可是出现的问题也不少,我这里加上主要缘由是当input失去焦点的时候,有的时候整个页面会卡顿住(这个问题在webview中碰到的),我发现加上这个以后会解决这个问题,就把这两个放到一块儿了,不须要的能够不加上这个相关的。
我用的是mint-ui开发的移动端,因此在输入框的时候就能够这样使用学习

<mt-field class="l-modal-body-input" v-reset-page :attr="{ maxlength: 15 }" v-model="name" label="姓名:"></mt-field>
滚动穿透问题

这个能够说也是很常见的问题了,在咱们作弹框滚动,如地址或时间picker选择器的时候,咱们在滚动选择时候,底部的页面也会跟着一块儿滚动,必定程度上影响了用户的体验。经查找研究,当咱们弹框的时候移除body的touchmove事件,是能够解决这个问题的:ui

// 锁定body滚动条--主要解决用户弹框滚动时的穿透
Vue.prototype.closeTouch = function () {
  document.getElementsByTagName('body')[0].addEventListener('touchmove', this.handler, {passive: false}) // 阻止默认事件
}
Vue.prototype.openTouch = function () {
  document.getElementsByTagName('body')[0].removeEventListener('touchmove', this.handler, {passive: false}) // 打开默认事件
}
handler: (e) => {
    e.preventDefault()
}

当咱们打开picker等弹框的时候,调用this.closeTouch(),锁定滚动,阻止默认事件。关闭弹框的时候调用this.openTouch()打开默认事件。过程虽然比较麻烦,但能实际解决问题!this

以上是我作iOS移动项目时遇到的比较常见的问题,但愿能对您有所帮助,若有更好的方法能够互相学习!prototype


此贴仅供参考学习,转载请注明出处!code

相关文章
相关标签/搜索