關(guān)于ios中碰到的軟鍵盤彈出摊滔,導(dǎo)致的底部輸入框定位出現(xiàn)問(wèn)題的解決方案
背景
目前正在做IM相關(guān)的H5頁(yè)面,碰到了ios下軟鍵盤彈出槐脏,底部fixed失效的問(wèn)題喉童。在ios下,body的高度不會(huì)隨著軟鍵盤的彈出而變小顿天,所以頂部和底部的fixed元素位置都變得不正確了堂氯。要解決蘋果輸入框彈起被軟鍵盤遮住的問(wèn)題,切記不能使用傳統(tǒng)的fixed或者absolute布局露氮,根本解決不了輸入框被遮住的問(wèn)題祖灰。網(wǎng)上看了很多的解決辦法都沒(méi)有實(shí)現(xiàn)。
解決方案
首先采用flex布局來(lái)定位頭部畔规,中間和底部
<div class="con">
<div class="top">頭部固定</div>
<div class="content">中間內(nèi)容區(qū)域</div>
<div class="bottom">底部輸入框: <input focus="focus" blur="blur" /></div>
</div>
.con{
display:flex;
}
.top,.bottom{
height:50px;
}
.content{
flex: 1 auto;
overflow:auto;
}
先看一下在不同ios版本中局扶,軟鍵盤彈出后輸入框的位置
ios版本 | 表現(xiàn) |
---|---|
10 | 輸入框頂?shù)搅塑涙I盤之上 |
11 | 輸入框頂?shù)搅塑涙I盤以上 |
12 | 輸入框位置并沒(méi)有發(fā)生改變 |
思路是這樣的:
- 當(dāng)輸入框focus的時(shí)候,調(diào)用getBoundingClientRect方法獲取矩形信息
- 延時(shí)100毫秒后叁扫,再次調(diào)用getBoundingClientRect方法獲取矩形信息
- 兩次信息的top值做一個(gè)差值三妈,如果>0則表示輸入框已經(jīng)在軟鍵盤之上
- top的差值===0,則表示輸入框的位置沒(méi)有發(fā)生改變,這里調(diào)用元素的scrollIntoView方法來(lái)強(qiáng)制使得輸入框滾動(dòng)到可視區(qū)莫绣,之后再通過(guò)getBoundingClientRect來(lái)獲取矩陣信息畴蒲,計(jì)算兩次top的差值得到軟鍵盤的高度。
- 隨后設(shè)置body的height = window.innerHeight - 軟鍵盤高度
- 再次調(diào)用輸入框的scrollIntoView(false);
- 當(dāng)輸入框blur的時(shí)候对室,重新設(shè)置body的height即可
{
focus:(e){
const originRect = e.target.getBoundingClientRect();
const isFirst = false;
setTimeout(()=>{
let rect = e.target.getBoundingClientRect();
if(isFirst){
if(rect.top - originRect.top<0){
// todo 設(shè)置body的height
document.body.style.height = window.innerHeight - (originRect.top - rect.top) + "px";
e.target.scrollIntoView(false);
return;
}
}
e.target.scrollIntoView(false);
setTimeout(()=>{
rect = e.target.getBoundingClientRect();
// 某些機(jī)型下模燥,得到的top為負(fù)值,直接使用window.innerHeight
if(rect.top>0){
document.body.style.height = window.innerHeight + "px";
}else{
document.body.style.height = window.innerHeight - (originRect.top - rect.top) + "px";
}
e.target.scrollIntoView(false);
},100);
isFirst = false;
},100);
},
blur:(){
document.body.style.height = "100%";
}
}
問(wèn)題解決掩宜,如有問(wèn)題蔫骂,可以郵件給我(nick121212@126.com)