前言
- 在遇到要输入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
)