ReactJS网站:Android/iOS端打开键盘时隐藏悬浮按钮的方法
嘿,这个需求在移动端开发里挺常见的,我给你分享几个在React项目里能轻松实现的方案,你可以根据自己的场景选:
方案一:监听窗口高度变化(通用型)
手机键盘弹出时,浏览器的视口可用高度会突然大幅降低,我们可以通过监听这个变化来控制悬浮按钮的显示隐藏。
在React里可以用useEffect钩子绑定窗口的resize事件,结合初始高度做对比判断:
import { useState, useEffect, useRef } from 'react'; const FloatingButton = () => { const [isVisible, setIsVisible] = useState(true); // 保存初始视口高度 const initialWindowHeight = useRef(window.innerHeight); useEffect(() => { const handleResize = () => { // 设定阈值,高度差超过200px就判定为键盘弹出(可根据需求调整) const heightDifference = initialWindowHeight.current - window.innerHeight; setIsVisible(heightDifference <= 200); }; window.addEventListener('resize', handleResize); // 组件卸载时移除监听 return () => window.removeEventListener('resize', handleResize); }, []); return isVisible ? ( <button style={{ position: 'fixed', bottom: '20px', right: '20px', padding: '12px 24px', backgroundColor: '#007bff', color: '#fff', border: 'none', borderRadius: '50px', cursor: 'pointer', fontSize: '16px' }} > 悬浮按钮 </button> ) : null; }; export default FloatingButton;
注意点:
- 阈值可以根据不同机型的键盘高度调整,200px是个比较通用的数值
- 如果担心屏幕旋转导致误判,可以额外监听屏幕方向变化,或者在旋转后更新初始高度
方案二:监听输入框焦点事件(精准触发)
键盘弹出大多是因为用户点击了输入类元素(输入框、文本域等),所以我们可以直接监听这些元素的焦点事件,精准控制按钮显示:
基础版(静态输入框)
import { useState, useEffect } from 'react'; const FloatingButton = () => { const [isVisible, setIsVisible] = useState(true); useEffect(() => { const hideButton = () => setIsVisible(false); const showButton = () => setIsVisible(true); // 给页面所有输入类元素绑定事件 const inputElements = document.querySelectorAll('input, textarea, select'); inputElements.forEach(el => { el.addEventListener('focus', hideButton); el.addEventListener('blur', showButton); }); return () => { // 移除监听避免内存泄漏 inputElements.forEach(el => { el.removeEventListener('focus', hideButton); el.removeEventListener('blur', showButton); }); }; }, []); return isVisible ? ( <button style={{ position: 'fixed', bottom: '20px', right: '20px', padding: '12px 24px', backgroundColor: '#007bff', color: '#fff', border: 'none', borderRadius: '50px', cursor: 'pointer', fontSize: '16px' }} > 悬浮按钮 </button> ) : null; }; export default FloatingButton;
优化版(支持动态输入框)
如果页面有异步加载的输入元素,用事件委托更靠谱:
useEffect(() => { const handleFocusIn = (e) => { // 判断触发焦点的元素是否是输入类 const targetTag = e.target.tagName.toUpperCase(); if (['INPUT', 'TEXTAREA', 'SELECT'].includes(targetTag)) { setIsVisible(false); } }; const handleFocusOut = () => { setIsVisible(true); }; // 监听document的焦点事件,覆盖所有动态元素 document.addEventListener('focusin', handleFocusIn); document.addEventListener('focusout', handleFocusOut); return () => { document.removeEventListener('focusin', handleFocusIn); document.removeEventListener('focusout', handleFocusOut); }; }, []);
方案三:组合两种方法(兼容性拉满)
如果想覆盖所有场景(比如语音输入唤起键盘、第三方输入法触发等),可以把两种方案结合起来:
// 核心逻辑就是同时绑定resize和焦点事件,取两者的判断结果 useEffect(() => { // 窗口高度变化的处理逻辑 const handleResize = () => { const heightDifference = initialWindowHeight.current - window.innerHeight; setIsVisible(heightDifference <= 200); }; // 焦点事件的处理逻辑 const handleFocusIn = (e) => { const targetTag = e.target.tagName.toUpperCase(); if (['INPUT', 'TEXTAREA', 'SELECT'].includes(targetTag)) { setIsVisible(false); } }; const handleFocusOut = () => { // 焦点失去后,再通过窗口高度判断是否要显示按钮 const heightDifference = initialWindowHeight.current - window.innerHeight; setIsVisible(heightDifference <= 200); }; window.addEventListener('resize', handleResize); document.addEventListener('focusin', handleFocusIn); document.addEventListener('focusout', handleFocusOut); return () => { window.removeEventListener('resize', handleResize); document.removeEventListener('focusin', handleFocusIn); document.removeEventListener('focusout', handleFocusOut); }; }, []);
这样不管是哪种方式唤起键盘,都能准确隐藏悬浮按钮,体验更流畅。
内容的提问来源于stack exchange,提问作者gurupal singh
相关产品推荐
相关产品推荐

