React中实现点击菜单外部隐藏移动端下拉菜单的方法
React移动端导航栏点击外部隐藏菜单的实现方案
要实现点击菜单外部隐藏导航下拉菜单,可以通过监听全局点击事件,并判断点击区域是否属于导航栏内部来完成,以下是具体实现步骤和代码:
实现思路
- 给导航栏根节点添加
ref,用于后续判断点击目标是否在导航范围内 - 使用
useEffect监听document的click事件 - 在事件回调中,检查点击的DOM元素是否包含在导航栏内,若不包含且菜单处于打开状态,则关闭菜单
- 组件卸载时移除事件监听,避免内存泄漏
修改后的完整代码
import React, { useState, useEffect, useRef } from 'react' import { Link } from 'react-router-dom' const NavBar = () => { const [isOpen, setIsOpen] = useState(false); const navRef = useRef(null); // 创建导航栏ref const displayResponsiveMenu = () => { setIsOpen(!isOpen) } useEffect(() => { const handleClickOutside = (event) => { // 如果菜单是打开状态,且点击的元素不在导航栏内部 if (isOpen && navRef.current && !navRef.current.contains(event.target)) { setIsOpen(false); } }; // 绑定全局点击事件 document.addEventListener('mousedown', handleClickOutside); // 组件卸载时移除事件监听 return () => { document.removeEventListener('mousedown', handleClickOutside); }; }, [isOpen]); // 依赖isOpen,状态变化时重新绑定 return ( <nav ref={navRef}> {/* 将ref绑定到导航根元素 */} <div className="flex items-center justify-between flex-wrap bg-teal-500 p-6"> {/* 保留原有logo或其他内容 */} <div className="block lg:hidden"> <button onClick={displayResponsiveMenu} className="flex items-center px-3 py-2 border rounded text-teal-200 border-teal-400 hover:text-white hover:border-white"> { !isOpen ? <svg className="fill-current h-3 w-3" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><title>Menu</title><path d="M0 3h20v2H0V3zm0 6h20v2H0V9zm0 6h20v2H0v-2z" /></svg> : <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 20 20" strokeWidth="1.5" stroke="currentColor" className="w-3 h-3"> <path strokeLinecap="round" strokeLinejoin="round" d="M6 18L18 6M6 6l12 12" /> </svg> } </button> </div> {/* 保留原有桌面端导航内容 */} </div> { isOpen ? <div className="flex items-center justify-between flex-wrap bg-teal-500 pl-6 pt-2 pb-2"> <ul> <li> <Link to="/users" className="block lg:mt-0 text-teal-200 hover:text-white mr-4"> Users </Link> </li> </ul> </div> : null } </nav> ) } export default NavBar
关键代码说明
useRef:创建navRef并绑定到<nav>元素,用于获取导航栏的DOM节点useEffect:在组件挂载时添加全局点击事件监听,当isOpen状态变化时更新监听逻辑;组件卸载时移除事件,防止内存泄漏contains方法:判断点击的目标元素是否在导航栏内部,若不在则关闭菜单
内容的提问来源于stack exchange,提问作者Popovkov57
相关产品推荐
相关产品推荐

