移動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

相關文章
相關標籤/搜索