iOS移動端軟鍵盤彈起空白和滾動穿透問題解決方案
引言
在做h5移動端項目的時候,給用戶一個十分友好的體驗是很必要的。最近抽空整理了下移動端(iOS端)項目中經(jīng)常碰到的兩個問題
鍵盤彈起空白
在我們點擊input
等彈出手機鍵盤,在點擊完成后經(jīng)常會在底部出現(xiàn)跟鍵盤同大小的空白,但是當我們滾動下頁面發(fā)現(xiàn)又好了,這個在iOS端可以說很常見的問題了(應(yīng)該是布局定位造成的,具體原因沒仔細研究),解決方法就是在結(jié)束輸入的時候控制滾動條偏移下就好。
下面是相關(guān)代碼:
.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
的值設(shè)為auto,防止?jié)L動穿透。當元素失去焦點的時候,我們把值恢復(fù)為touch,這樣頁面的滾動效果不會丟失,同時我們控制滾動條偏移了1像素
,解決軟鍵盤彈起空白的問題。
關(guān)于我設(shè)置的-webkit-overflow-scrolling
屬性可多說兩句:
// -webkit-overflow-scrolling這個樣式相信大家都很熟悉了,有auto、touch兩個可選值 // auto:使用普通滾動, 當手指從觸摸屏上移開,滾動會立即停止。 // touch:使用具有回彈效果的滾動, 當手指從觸摸屏上移開,內(nèi)容會繼續(xù)保持一段時間的滾動效果。繼續(xù)滾動的速度和持續(xù)的時間和滾動手勢的強烈程度成正比。同時也會創(chuàng)建一個新的堆棧上下文。 // 為了增加滾動的流暢性,做iOS移動端適配的時候都會增加這個樣式適配的 -webkit-overflow-scrolling: touch;
查看兼容性的事后素我們發(fā)現(xiàn)只在iOS端可用,但是出現(xiàn)的問題也很多,我這里加上主要原因是當input失去焦點的時候,有的時候整個頁面會卡頓?。ㄟ@個問題在webview
中碰到的),我發(fā)現(xiàn)加上這個之后會解決這個問題,就把這兩個放到一起了,不需要的可以不加上這個相關(guān)的。
我用的是mint-ui
開發(fā)的移動端,所以在輸入框的時候就可以這樣使用
<mt-field class="l-modal-body-input" v-reset-page :attr="{ maxlength: 15 }" v-model="name" label="姓名:"></mt-field>
滾動穿透問題
這個可以說也是很常見的問題了,在我們做彈框滾動,如地址或時間picker
選擇器的時候,我們在滾動選擇時候,底部的頁面也會跟著一起滾動,一定程度上影響了用戶的體驗。經(jīng)查找研究,當我們彈框的時候移除body的touchmove
事件,是可以解決這個問題的:
// 鎖定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等彈框的時候,調(diào)用this.closeTouch()
,鎖定滾動,阻止默認事件。關(guān)閉彈框的時候調(diào)用this.openTouch()
打開默認事件。過程雖然比較麻煩,但能實際解決問題!
以上是我做iOS移動項目時遇到的比較常見的問題,更多關(guān)于iOS軟鍵盤彈起空白滾動穿透的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Flutter Widgets MediaQuery控件屏幕信息適配
這篇文章主要為大家介紹了Flutter Widgets 之 MediaQuery控件獲取屏幕信息和屏幕適配示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-11-11