前言
- 在遇到要輸入input時,安卓系統的瀏覽器會彈起鍵盤但頁面原樣。ios系統彈起鍵盤後可以滾動。所以這個優化只對安卓生效。
原理
- 安卓的鍵盤彈起就是個resize事件。通過監聽resize事件,以及判斷瀏覽器ua來進行處理。
- 另外還有個activeElement可以拿到激活的input,通過scrollIntoView更好的來進行優化可視效果。
最終效果
- 這個是真機連chrome進行測試,chrome看不見手機鍵盤。
代碼
import {useState,useEffect}from 'react'
interface DomArgs{
height: number;
bottom: number;
}
export function useKeyBoardSolve(name: string,domargs: DomArgs,difference: number,fixDifference: number){
const [originHeight]=useState(document.documentElement.clientHeight||document.body.clientHeight)
const [scrollOrigin,setScrollOrigin]=useState({
sign:true,
height:0,
})
const [origin,setOrigin]=useState({
height:0,
bottom:0
})
const resizeHandler=()=>{
const resizeHeight = document.documentElement.clientHeight||document.body.clientHeight
const activeElement =document.activeElement
const scrollDom =document.querySelector<HTMLFormElement>(`.${name}`)
const scrollHeight = scrollDom?.getBoundingClientRect().height
if(resizeHeight<originHeight){
if(activeElement&&(activeElement.tagName==='INPUT'||activeElement.tagName==='TEXTAREA')){
if(scrollDom&&scrollHeight){
setScrollOrigin({
sign:false,
height:originHeight-resizeHeight,
})
setTimeout(() => {
activeElement.scrollIntoView({block:"center"})
});
}
}
}else{
if(scrollDom&&scrollHeight){
setScrollOrigin({
sign:true,
height:0
})
}
}
}
useEffect(()=>{
setOrigin({
height:domargs.height,
bottom:domargs.bottom
})
},[domargs])
useEffect(()=>{
const scrollDom =document.querySelector<HTMLFormElement>(`.${name}`)
if(scrollOrigin.sign){
if(scrollDom&&origin.height!==0){
scrollDom.style.height=origin.height+'px'
scrollDom.style.overflow='scroll'
}
}else{
if(scrollDom){
if(origin.bottom<(scrollOrigin.height+difference+fixDifference)){
scrollDom.style.height = origin.height-(scrollOrigin.height-origin.bottom+difference+fixDifference) +'px'
scrollDom.style.overflow='scroll'
}
}
}
},[scrollOrigin])
useEffect(()=>{
const ua = window.navigator.userAgent.toLocaleLowerCase()
const isAndroid = ua.includes('android')
if(isAndroid){
window.addEventListener('resize',resizeHandler)
}
},[])
}
useKeyBoardSolve('ant-form',useheight,parseFloat(document.documentElement.style.fontSize)*1.2,
parseFloat(document.documentElement.style.fontSize)*2
)