react在安卓中輸入框被手機鍵盤遮擋問題的解決方法
前言
React 起源于 Facebook 的內(nèi)部項目,因為該公司對市場上所有 JavaScript MVC 框架,都不滿意,就決定自己寫一套,用來架設 Instagram 的網(wǎng)站。做出來以后,發(fā)現(xiàn)這套東西很好用,就在2013年5月開源了。
本文主要介紹了關(guān)于react在安卓輸入框被鍵盤遮擋的相關(guān)內(nèi)容,分享出來動大家參考學習,下面話不多說了,來一起看看詳細的介紹吧
問題概述
今天遇到了一個問題,在安卓手機上,當我要點擊輸入“店鋪名稱”時,手機軟鍵盤彈出來剛好把輸入框擋住了;擋住就算了,關(guān)鍵是頁面還不能向上滑動,整個手機窗口被壓為原來的二分之一左右;

然后
然后找了一些方案,不過不大適用,或者是有點麻煩;所以需要整合一下,
首先,我想一下我要實現(xiàn)的效果(2018/9/3補充:評論區(qū)有更加簡單的實現(xiàn)方法)
想要實現(xiàn)的效果

如圖,當手機鍵盤出現(xiàn)時,頁面是可以自由滾動的,而且當前聚焦的輸入框往紅線處靠齊,這樣就剛好在剩下的窗口的垂直正中間,這樣就不會出現(xiàn)輸入框被擋住,看不到自己輸入的內(nèi)容了 ;
第一步,使屏幕壓小時,頁面內(nèi)容可以滾動查看
如下圖所示,黑色框代表屏幕,藍色框代表頁面大小,當屏幕被壓小時,頁面內(nèi)容必須保持原來的高度:

實現(xiàn)原理,頁面一進來時,我就獲取窗口的高度,給最外層的div設置一個最小高度,這樣就算窗口壓小了,頁面還能維持原來的高度,可以滾動瀏覽:
let initWindowHeight=window.innerHeight
let wrapDiv=document.getElementsByClassName('animated-router-forward-enter-done')[0]
wrapDiv.style.minHeight =initWindowHeight+'px'
第二步,滾到紅線處
由于我們不能直接知道軟鍵盤什么時候出來,不過軟鍵盤出來的時候窗口高度會縮小,所以我們可以通過監(jiān)聽窗口大小變化事件來判斷軟鍵盤是否彈出,比如瀏覽器窗口高度突然縮小25%以上,那么我們就認為是軟鍵盤出來了,然后我們獲取聚焦input距離頁面頂部的距離,計算距離紅線有多少距離,假設距離是60,那么我們就讓頁面向上滾動60,這時input就剛剛好到了紅線處;
window.onresize=function(){
if(initWindowHeight-window.innerHeight>initWindowHeight/4&&document.querySelectorAll(':focus').length>0){
//offset是封裝好的一個獲取元素距離頁面頂部滾動距離的方法
if(offset(document.querySelectorAll(':focus')[0]).top>initWindowHeight/4){
document.body.scrollTop=offset(document.querySelectorAll(':focus')[0]).top-initWindowHeight/4
}
}else if(window.innerHeight-initWindowHeight<20){
document.body.scrollTop=0
}
};
完整代碼
因為可能有多個頁面要調(diào)用,所以我把代碼放到一個單獨的js文件中:
function pageInputScroll() {
let initWindowHeight=window.innerHeight
setTimeout(() => {
let wrapDiv=document.getElementsByClassName('animated-router-forward-enter-done')[0]
//console.log(wrapDiv.style)
wrapDiv.style.minHeight =initWindowHeight+'px'
}, 500);
//由于我們不能直接知道軟鍵盤什么時候出來,不過軟鍵盤出來的時候窗口高度會縮小,所以我們可以通過監(jiān)聽窗口大小變化事件來判斷軟鍵盤是否彈出
window.onresize=function(){ //如果瀏覽器窗口高度縮小25%以上,就認為是軟鍵盤出來了
if(initWindowHeight-window.innerHeight>initWindowHeight/4&&document.querySelectorAll(':focus').length>0){
if(offset(document.querySelectorAll(':focus')[0]).top>initWindowHeight/4){
document.body.scrollTop=offset(document.querySelectorAll(':focus')[0]).top-initWindowHeight/4
}
}else if(window.innerHeight-initWindowHeight<20){
document.body.scrollTop=0
}
};
}
function offset(element) {
var offest = {
top: 0,
left: 0
};
var _position;
getOffset(element, true);
return offest;
// 遞歸獲取 offset, 可以考慮使用 getBoundingClientRect
function getOffset(node, init) {
// 非Element 終止遞歸
if (node.nodeType !== 1) {
return;
}
_position = window.getComputedStyle(node)['position'];
// position=static: 繼續(xù)遞歸父節(jié)點
if (typeof(init) === 'undefined' && _position === 'static') {
getOffset(node.parentNode);
return;
}
offest.top = node.offsetTop + offest.top - node.scrollTop;
offest.left = node.offsetLeft + offest.left - node.scrollLeft;
// position = fixed: 獲取值后退出遞歸
if (_position === 'fixed') {
return;
}
getOffset(node.parentNode);
}
}
export {pageInputScroll};
在react頁面中引入js并調(diào)用:
import {pageInputScroll} from '../../util/pageInputScroll'
......
componentDidMount(){
pageInputScroll()
}
如果只是想在安卓下使用,可以加一個判斷:
if(/Android/i.test(navigator.userAgent)){
pageInputScroll()
}
效果動圖
我在pc端的谷歌瀏覽器模擬一下實現(xiàn)的效果:

備注
offset()方法是使用js實現(xiàn)類似jquery的offset()的一個方法,參考自:原生js實現(xiàn)offset方法
總結(jié):
以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對腳本之家的支持。
相關(guān)文章
react hook使用useState更新數(shù)組,無法更新問題及解決
這篇文章主要介紹了react hook使用useState更新數(shù)組,無法更新問題及解決,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-03-03
詳解React-Native全球化多語言切換工具庫react-native-i18n
這篇文章主要介紹了詳解React-Native全球化語言切換工具庫react-native-i18n,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-11-11
ForwardRef?useImperativeHandle方法demo
這篇文章主要為大家介紹了ForwardRef?useImperativeHandle方法demo,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-03-03

