解決IOS下軟鍵盤彈出導(dǎo)致的固定定位失效問題

在IOS系統(tǒng)下的H5頁面中,軟鍵盤彈出會對頁面布局產(chǎn)生一些問題,其中最典型的就是元素固定定位失效問題。

一、分析原因

當(dāng)軟鍵盤彈出時,在Android系統(tǒng)下,H5所在容器(即WebView)高度會被壓縮,而IOS系統(tǒng)下則不會發(fā)生改變,軟鍵盤是從底部彈出直接覆蓋在WebView上的,從而造成部分內(nèi)容會被軟鍵盤遮擋,這時WebView出現(xiàn)滾動條。

一般情況下,固定定位可以讓元素相對于WebView進(jìn)行定位,但是軟鍵盤的出現(xiàn),導(dǎo)致相對于WebView定位的元素可能被遮擋,只有通過滑動頁面的方式讓被遮擋的元素顯示出來,而這時固定定位就看起來似乎“失效”了。

滑動頁面顯示固定定位元素

上圖虛線部分是設(shè)備的可視窗口,底部有個固定定位元素。當(dāng)軟鍵盤拉起時,該元素會被軟鍵盤遮擋(如左圖所示),此時WebView可滑動,上滑頁面直至滾動條到最底部時,固定定位元素才能最終顯示在軟鍵盤頂部(如右圖所示)。

如此可見,元素雖然還是相對于WebView進(jìn)行定位,但由于軟鍵盤遮擋而出現(xiàn)滾動條的緣故,導(dǎo)致固定定位看起來好像“失效”了。

接下來,我將以上述底部固定定位的案例來探討具體解決固定定位失效問題的方案。

二、解決問題

以上案例基礎(chǔ)頁面布局代碼如下:

<!-- HTML -->
<form id="form">
  <textarea id="editor" cols="30" rows="10"></textarea>
  <div id="toolbar">固定定位元素</div>
</form>
/* css */
html,
body,
form {
  height: 100%;
}
form {
  overflow: auto;
  -webkit-overflow-scrolling: touch;
}
#toolbar {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 50px;
}

1. 固定定位元素被軟鍵盤遮擋問題

這個問題我們可以通過scrollIntoView()方法來解決,scrollIntoView()是DOM元素上的一個方法,該方法可滾動元素的父容器,使被調(diào)用scrollIntoView()的元素對用戶可見。

let editor = document.getElementById('editor'), 
    form = document.getElementById('form'),
    toolbar = document.getElementById('toolbar');
// 編輯器獲取焦點時滾動容器至toolbar元素可見
editor.addEventListener('focus', () => {
  setTimeout(() => {   // 延遲執(zhí)行是為了保證鍵盤已拉起
    toolbar.scrollIntoView();
  }, 300);
});

2. 容器滾動導(dǎo)致編輯器不在可視區(qū)問題

當(dāng)使用scrollIntoView()后底部定位元素雖然可見,但也同時可能導(dǎo)致位于頁面頂部的編輯器滾動到可視區(qū)之外。

要解決這個問題,我們可以直接在編輯器獲取焦點時將底部定位元素的bottom值設(shè)為軟鍵盤高度,而軟鍵盤高度無法直接獲得,但可以通過上面scrollIntoView()導(dǎo)致的容器滾動高度來間接獲得。

let boardHeight = 0;
editor.addEventListener('focus', () => {
  setTimeout(() => { 
    toolbar.scrollIntoView();
    // 鍵盤高度 = 容器滾動高度
    boardHeight = document.documentElement.scrollTop || document.body.scrollTop;
    toolbar.style.bottom = boardHeight + 'px';
    scrollTo(0, 0);  // 最后記得要讓頁面回到頂部,讓頁面頂部的編輯器回到可視區(qū)內(nèi)
  }, 300);
});

3. 滑動頁面時定位元素錯位問題

由于固定定位失效而使用絕對定位替代,所以當(dāng)我們滑動頁面時,定位元素自然是不能始終固定在底部,而是隨著頁面滑動而上下移動。為了解決這個問題,我們可以在滑動頁面時讓軟鍵盤拉起,并讓定位元素的bottom值重新回到初始值(本文例子是0)。

editor.addEventListener('blur', () => {
   toolbar.style.bottom = 0;
});
document.addEventListener('touchmove', () => {
  editor.blur();
});

結(jié)束語

本文介紹的方法并非最終完美的解決方案,比如當(dāng)編輯器位于頁面底部位置而非頂部時,該方案將會出現(xiàn)問題。如果看完本文覺得有不對之處或有更好解決方案,歡迎提出和指正,謝謝!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容