Chrome 107旧版本打开键盘时innerHeight异常,React横屏判断修复
修复Chrome 107旧版本唤起键盘导致横屏判断错误的方案
方案1:使用screen.orientation API(最推荐)
这个API直接获取设备的物理屏幕方向,不受软键盘唤起导致的视口变化干扰,Chrome 107完全支持该接口。
实现思路:
- 通过
screen.orientation.type判断方向:包含landscape则为横屏,包含portrait则为竖屏 - 监听
orientationchange事件,在屏幕物理旋转时更新判断状态
React自定义Hook示例:
import { useState, useEffect } from 'react'; function useDeviceOrientation() { const [isLandscape, setIsLandscape] = useState(false); const updateOrientation = () => { setIsLandscape(screen.orientation.type.includes('landscape')); }; useEffect(() => { updateOrientation(); screen.orientation.addEventListener('change', updateOrientation); return () => screen.orientation.removeEventListener('change', updateOrientation); }, []); return isLandscape; } // 组件中使用 function DemoComponent() { const isLandscape = useDeviceOrientation(); return <div>当前模式:{isLandscape ? '横屏' : '竖屏'}</div>; }
方案2:结合屏幕物理尺寸过滤键盘干扰
如果对screen.orientation有兼容性顾虑(实际Chrome 107无需担心),可以通过屏幕物理尺寸和视口尺寸的差异,判断是否为键盘唤起导致的视口变化,从而避免误判横竖屏。
实现思路:
- 先通过
screen.width和screen.height确定设备的物理横竖屏方向 - 监听视口
resize事件,当视口高度远小于物理高度(比如差值超过200px),判定为键盘唤起,保持原方向判断;否则用视口宽高比更新判断
React自定义Hook示例:
import { useState, useEffect } from 'react'; function useDeviceOrientation() { // 初始物理方向判断 const [baseIsLandscape] = useState(screen.width > screen.height); const [isLandscape, setIsLandscape] = useState(baseIsLandscape); const updateOrientation = () => { // 阈值可根据设备调整,避免误判 const isKeyboardOpen = screen.height - window.innerHeight > 200; if (isKeyboardOpen) { setIsLandscape(baseIsLandscape); } else { setIsLandscape(window.innerWidth > window.innerHeight); } }; useEffect(() => { updateOrientation(); window.addEventListener('resize', updateOrientation); return () => window.removeEventListener('resize', updateOrientation); }, [baseIsLandscape]); return isLandscape; }
方案3:使用matchMedia监听设备方向媒体查询
部分旧版Chrome中,(orientation: landscape)媒体查询已优先基于设备物理方向(可真机测试验证),如果测试可用,也可以采用这个方案:
React自定义Hook示例:
import { useState, useEffect } from 'react'; function useDeviceOrientation() { const [isLandscape, setIsLandscape] = useState(false); const landscapeQuery = window.matchMedia('(orientation: landscape)'); const handleOrientationChange = (e) => { setIsLandscape(e.matches); }; useEffect(() => { setIsLandscape(landscapeQuery.matches); landscapeQuery.addEventListener('change', handleOrientationChange); return () => landscapeQuery.removeEventListener('change', handleOrientationChange); }, []); return isLandscape; }
注意事项:
- 方案1是最可靠的,完全规避软键盘干扰,优先使用
- 方案2的高度阈值可根据目标设备调整,避免误判
- 需在Chrome 107旧版本真机环境测试验证,模拟器可能存在偏差
内容的提问来源于stack exchange,提问作者vantrong
相关产品推荐
相关产品推荐

