【React】使用自定义hook解决安卓键盘弹起遮挡

前言

  • 在遇到要输入input时,安卓系统的浏览器会弹起键盘但页面原样。ios系统弹起键盘后可以滚动。所以这个优化只对安卓生效。

原理

  • 安卓的键盘弹起就是个resize事件。通过监听resize事件,以及判断浏览器ua来进行处理。
  • 另外还有个activeElement可以拿到激活的input,通过scrollIntoView更好的来进行优化可视效果。

最终效果

  • 这个是真机连chrome进行测试,chrome看不见手机键盘。
    在这里插入图片描述

代码

import {useState,useEffect}from 'react'

interface DomArgs{
	height: number;
	bottom: number;
}
/**
 *
 *
 * @param {string} 滚动dom
 * @param {DomArgs} 滚动dom高和底部高,异步获取
 * @param {number} difference 滚动dom高最后需要减去的差值
 * @param {number} fixDifference 绝对定位元素,随着键盘一起移动高度
 */
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){//如果键盘高度比dom底部高度大,应该dom原本高度减去底部高度与键盘高度的差
				if(origin.bottom<(scrollOrigin.height+difference+fixDifference)){
					scrollDom.style.height = origin.height-(scrollOrigin.height-origin.bottom+difference+fixDifference) +'px'
					scrollDom.style.overflow='scroll'
				}//键盘没dom底部长不需要卷曲
			}
		}
	},[scrollOrigin])
	useEffect(()=>{
		const ua = window.navigator.userAgent.toLocaleLowerCase()
		// const isIOS = /iphone|ipad|ipod/.test(ua);
		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
	)
  • 注释都有,自己看就行。
发布了178 篇原创文章 · 获赞 11 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/yehuozhili/article/details/105394458