- 資訊首頁(yè) > 開(kāi)發(fā)技術(shù) > web開(kāi)發(fā) >
- react在安卓中輸入框被手機鍵盤(pán)遮擋怎么辦
這篇文章主要介紹react在安卓中輸入框被手機鍵盤(pán)遮擋怎么辦,文中介紹的非常詳細,具有一定的參考價(jià)值,感興趣的小伙伴們一定要看完!
問(wèn)題概述
今天遇到了一個(gè)問(wèn)題,在安卓手機上,當我要點(diǎn)擊輸入“店鋪名稱(chēng)”時(shí),手機軟鍵盤(pán)彈出來(lái)剛好把輸入框擋住了;擋住就算了,關(guān)鍵是頁(yè)面還不能向上滑動(dòng),整個(gè)手機窗口被壓為原來(lái)的二分之一左右;
然后
然后找了一些方案,不過(guò)不大適用,或者是有點(diǎn)麻煩;所以需要整合一下,
首先,我想一下我要實(shí)現的效果(2018/9/3補充:評論區有更加簡(jiǎn)單的實(shí)現方法)
想要實(shí)現的效果
如圖,當手機鍵盤(pán)出現時(shí),頁(yè)面是可以自由滾動(dòng)的,而且當前聚焦的輸入框往紅線(xiàn)處靠齊,這樣就剛好在剩下的窗口的垂直正中間,這樣就不會(huì )出現輸入框被擋住,看不到自己輸入的內容了 ;
第一步,使屏幕壓小時(shí),頁(yè)面內容可以滾動(dòng)查看
如下圖所示,黑色框代表屏幕,藍色框代表頁(yè)面大小,當屏幕被壓小時(shí),頁(yè)面內容必須保持原來(lái)的高度:
實(shí)現原理,頁(yè)面一進(jìn)來(lái)時(shí),我就獲取窗口的高度,給最外層的div設置一個(gè)最小高度,這樣就算窗口壓小了,頁(yè)面還能維持原來(lái)的高度,可以滾動(dòng)瀏覽:
let initWindowHeight=window.innerHeight let wrapDiv=document.getElementsByClassName('animated-router-forward-enter-done')[0] wrapDiv.style.minHeight =initWindowHeight+'px'
第二步,滾到紅線(xiàn)處
由于我們不能直接知道軟鍵盤(pán)什么時(shí)候出來(lái),不過(guò)軟鍵盤(pán)出來(lái)的時(shí)候窗口高度會(huì )縮小,所以我們可以通過(guò)監聽(tīng)窗口大小變化事件來(lái)判斷軟鍵盤(pán)是否彈出,比如瀏覽器窗口高度突然縮小25%以上,那么我們就認為是軟鍵盤(pán)出來(lái)了,然后我們獲取聚焦input距離頁(yè)面頂部的距離,計算距離紅線(xiàn)有多少距離,假設距離是60,那么我們就讓頁(yè)面向上滾動(dòng)60,這時(shí)input就剛剛好到了紅線(xiàn)處;
window.onresize=function(){ if(initWindowHeight-window.innerHeight>initWindowHeight/4&&document.querySelectorAll(':focus').length>0){ //offset是封裝好的一個(gè)獲取元素距離頁(yè)面頂部滾動(dòng)距離的方法 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 } };
完整代碼
因為可能有多個(gè)頁(yè)面要調用,所以我把代碼放到一個(gè)單獨的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); //由于我們不能直接知道軟鍵盤(pán)什么時(shí)候出來(lái),不過(guò)軟鍵盤(pán)出來(lái)的時(shí)候窗口高度會(huì )縮小,所以我們可以通過(guò)監聽(tīng)窗口大小變化事件來(lái)判斷軟鍵盤(pán)是否彈出 window.onresize=function(){ //如果瀏覽器窗口高度縮小25%以上,就認為是軟鍵盤(pán)出來(lái)了 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: 繼續遞歸父節點(diǎn) 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頁(yè)面中引入js并調用:
import {pageInputScroll} from '../../util/pageInputScroll' ...... componentDidMount(){ pageInputScroll() }
如果只是想在安卓下使用,可以加一個(gè)判斷:
if(/Android/i.test(navigator.userAgent)){ pageInputScroll() }
效果動(dòng)圖
我在pc端的谷歌瀏覽器模擬一下實(shí)現的效果:
備注
offset()方法是使用js實(shí)現類(lèi)似jquery的offset()的一個(gè)方法,參考自:原生js實(shí)現offset方法
免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng )、來(lái)自互聯(lián)網(wǎng)轉載和分享為主,文章觀(guān)點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權請聯(lián)系站長(cháng)郵箱:ts@56dr.com進(jìn)行舉報,并提供相關(guān)證據,一經(jīng)查實(shí),將立刻刪除涉嫌侵權內容。
Copyright ? 2009-2021 56dr.com. All Rights Reserved. 特網(wǎng)科技 版權所有 珠海市特網(wǎng)科技有限公司 粵ICP備16109289號
域名注冊服務(wù)機構:阿里云計算有限公司(萬(wàn)網(wǎng)) 域名服務(wù)機構:煙臺帝思普網(wǎng)絡(luò )科技有限公司(DNSPod) CDN服務(wù):阿里云計算有限公司 中國互聯(lián)網(wǎng)舉報中心 增值電信業(yè)務(wù)經(jīng)營(yíng)許可證B2 建議您使用Chrome、Firefox、Edge、IE10及以上版本和360等主流瀏覽器瀏覽本網(wǎng)站