在 H5 項目中,咱們會常常遇到頁面中存在單個甚至多個 input/textarea 輸入框與底部固定元素的佈局狀況。在 input/textarea 輸入框獲取焦點時,會自動觸發鍵盤彈起,而鍵盤彈出在 ios 與 android 的 webview 中表現並不是一致,同時當咱們主動觸發鍵盤收起時也一樣存在差別化。而不管如何,咱們但願功能流暢的同時,儘可能保持用戶體驗的一致性,所以有了下面一系列兼容性問題的研究。android
鍵盤高度 + 頁面高度 = 原頁面高度;
是錯誤的誤導,只有在某種很巧合的佈局狀況下才可套用此公式。在 h5 中目前沒有接口能夠直接監聽鍵盤事件,但咱們能夠經過分析鍵盤彈出、收起的觸發過程及表現形式,來判斷鍵盤是彈出仍是收起的狀態。ios
下面舉例說明,其中頁面中含有一個輸入框:web
<div class="txd">
Welcome to TXD!
</div>
<div class="input">
<input id="input" type="tel" />
</div>
複製代碼
ios & android 鍵盤彈出:瀏覽器
const $input = document.getElementById('input');
$input.addEventListener('focus', () => {
// 處理鍵盤彈出後所需的頁面邏輯
}, false);
複製代碼
ios 鍵盤收起:bash
const $input = document.getElementById('input');
$input.addEventListener('blur', () => {
// 處理鍵盤收起後所需的頁面邏輯
}, false);
複製代碼
android 鍵盤彈出與收起:iphone
/*鍵盤彈起後頁面高度變小*/
const originHeight = document.documentElement.clientHeight || document.body.clientHeight;
window.addEventListener('resize', () => {
const resizeHeight = document.documentElement.clientHeight || document.body.clientHeight;
if (resizeHeight < originHeight) {
// 鍵盤彈起所後所需的頁面邏輯
} else {
// 鍵盤彈起所後所需的頁面邏輯
}
}, false);
複製代碼
在實踐中經過判斷 userAgent 來決定使用哪一種方法:佈局
const ua = window.navigator.userAgent.toLocaleLowerCase();
const isIOS = /iphone|ipad|ipod/.test(ua);
const isAndroid = /android/.test(ua);
複製代碼
接下來根據上面的討論說明幾種常見場景:優化
(1)頭部及中間輸入框處於正常的文檔流,底部元素 fixed
ui
ios 鍵盤遮擋在頁面上,頁面高度始終不變,頁面能夠滾動,底部元素被遮擋;spa
android 頁面高度減小,頁面不可滾動,fixed 元素的 bottom 屬性的基線爲鍵盤;
(2)頭部及輸入框處於正常文檔流,且所佔可視區域變大,底部元素 fixed
ios 的 height 沒有發生變化,頁面能夠滾動;
android 頁面高度變小,但爲了使正常文檔流的元素能夠正常顯示,頁面能夠上下滾動,fixed 元素的 bottom 屬性的基線爲鍵盤;
(3)頭部處於正常文檔流,輸入框脫離正常文檔流 fixed bottom 定位
ios 的 height 沒有發生變化,且始終保證輸入框處於可視區域中;
android 頁面高度變小,頁面不可滾動,fixed 輸入框 bottom 屬性的基線爲鍵盤;
在瞭解清楚 h5 中鍵盤的彈出收起的性質後,在處理兼容性問題會容易不少。同時也可以使用Element.scrollIntoViewIfNeeded() 方法輔助解決問題(好比在切換不一樣的輸入法時,可能致使有用信息被遮擋的狀況)優化體驗。