概述
近期有個移動端頁面的項目,存在需要用戶輸入的表單信息。因為頁面不存在滑動(通過overflow
設為hidden
的方式),所以在點擊input
標簽輸入信息時,在安卓機下鍵盤會遮擋頁面底部內容,當點擊鍵盤時,焦點所在的 input
標簽才會顯示在視區里。在IOS不存在此問題(在軟鍵盤彈出時,頁面會自動頂上去),存在滑動的頁面里也不存在該問題。
目前的解決方案一覽
- 通過
window.onresize
監聽頁面大小變化,然后通過window.scrollTo
使頁面滾動到所需位置 - 通過
Element.scrollIntoView()
- 通過
Element.scrollIntoViewIfNeeded()
window.scrollTo
沒什么好解釋的上代碼
window.onresize = function () {
if (document.activeElement.tagName == "INPUT" || document.activeElement.tagName == "TEXTAREA") {
setTimeout(function () {
var top = document.activeElement.getBoundingClientRect().top;
window.scrollTo(0,top);
}, 0);
}
}
提一下,因為iphone不存在此問題,可以加一個限制條件在android以外的終端下不執行此端代碼
var ua = navigator.userAgent;
var isAndroid = /android/i.test(ua); //android終端
if(!isAndroid) {
//執行代碼.....
}
提個問題,如果這段代碼放在放在 input
等輸入標簽內可以么?
經過個人測試不可以,大家有興趣可以自行測試,如果有可以的機型可以拿出來探討。
對這個問題我還想分析下,首先我的頁面是不可滾動的,正常情況執行 window.scrollTo
是不會有作用的,但是當彈出軟鍵盤時,頁面由於被軟鍵盤頂起,致使頁面高度發生了變化,所以此時執行 window.scrollTo
頁面會發生變化。但是,由於js觸發事件,onresize
事件要在 click
事件之后,不是捕獲和冒泡的問題哦。我嘗試添加setTimeout,但是這個事件差不同的機型間會存在差異,如果設太長,就又失去了該解決方案的意義了,關於這個見仁見智吧。
關於此段,持續更新,歡迎交流學習
Element.scrollIntoView()
在MDN中有提到這個是一個實驗功能,但他的支持度還是可以的,根據項目情況選擇吧。
其作用就是讓當前的元素滾動到瀏覽器窗口的可視區域內
使用方式如下
element.scrollIntoView(); // 等同於element.scrollIntoView(true)
element.scrollIntoView(alignToTop); // Boolean型參數
element.scrollIntoView(scrollIntoViewOptions); // Object型參數
參數分兩種
alignToTop
一個Boolean值:
- 如果為true,元素的頂端將和其所在滾動區的可視區域的頂端對齊。
- 如果為true,元素的頂端將和其所在滾動區的可視區域的頂端對齊。
- 如果為false,元素的底端將和其所在滾動區的可視區域的底端對齊。
scrollIntoViewOptions
一個boolean或一個帶有選項的object:
{
behavior: "auto" | "instant" | "smooth",
block: "start" | "end",
}
如果是一個boolean, true 相當於{block: "start"},false 相當於{block: "end"}
scrollIntoViewOptions
支持度很低, 不建議使用
Element.scrollIntoViewIfNeeded()
在MDN中有提到:
該特性是非標准的,請盡量不要在生產環境中使用它!
但他的支持度還是蠻高的的,根據項目情況選擇吧。
用法類似與 Element.scrollIntoView()
,但它只有一個參數
opt_center
一個 Boolean 類型的值,默認為true:
- 如果為true,則元素將在其所在滾動區的可視區域中居中對其。
- 如果為false,則元素將與其所在滾動區的可視區域最近的邊緣對齊。 根據可見區域最靠近元素的哪個邊緣,元素的頂部將與可見區域的頂部邊緣對准,或者元素的底部邊緣將與可見區域的底部邊緣對准。