如何让同一按钮同时触发OnMouseOver与onClick事件(React+MUI)
解决React+MUI导航Hover显示菜单与Click滚动的事件冲突问题
核心问题分析
你的代码存在基础语法错误,同时事件冲突源于菜单状态管理与按钮事件的触发逻辑未协调:hover打开菜单后,点击按钮时菜单的关闭事件可能干扰点击事件执行,或状态更新导致事件触发异常。
修正后的完整代码
import { useState } from 'react'; import { Button, Menu, MenuItem } from '@mui/material'; function Navbar() { const [anchorEl, setAnchorEl] = useState(null); // 统一关闭菜单的方法 const handleCloseMenu = () => { setAnchorEl(null); }; // 点击按钮执行滚动逻辑 const handleClickNav = () => { handleCloseMenu(); // 先关闭菜单,避免状态冲突 console.log('执行滚动到对应区域的逻辑'); // 这里添加实际滚动代码,比如: // document.getElementById('about-us-section').scrollIntoView({ behavior: 'smooth' }); }; return ( <div onMouseLeave={handleCloseMenu}> {/* 容器统一处理鼠标离开关闭菜单 */} <Button style={{ textTransform: 'none' }} name="el1" aria-controls="simple-menu" aria-haspopup="true" onMouseOver={(e) => setAnchorEl(e.currentTarget)} onClick={handleClickNav} > <p className="text-slate-200 text-md">About Us</p> </Button> <Menu id="simple-menu" name="el1" anchorEl={anchorEl} keepMounted open={Boolean(anchorEl)} onClose={handleCloseMenu} // 点击外部区域关闭菜单 anchorOrigin={{ vertical: 'bottom', horizontal: 'left' }} // 调整菜单定位避免遮挡按钮 > <MenuItem onClick={handleCloseMenu}> <p className="text-sm">Menu Item 1</p> </MenuItem> <MenuItem onClick={handleCloseMenu}> <p className="text-sm">Menu Item 2</p> </MenuItem> <MenuItem onClick={handleCloseMenu}> <p className="text-sm">Menu Item 3</p> </MenuItem> </Menu> </div> ); } export default Navbar;
关键优化点
- 统一菜单关闭逻辑:定义
handleCloseMenu方法集中处理菜单关闭,避免重复代码 - 容器包裹处理鼠标离开:用
<div>包裹按钮和菜单,添加onMouseLeave事件,鼠标离开整个导航区域时自动关闭菜单 - 点击按钮先关菜单:在
handleClickNav中先关闭菜单,确保状态更新后再执行滚动逻辑,避免状态冲突导致事件失效 - 修复语法错误:修正函数定义错误,补充缺失的关闭方法,确保代码可运行
扩展说明
如果需要菜单项也执行滚动逻辑,只需修改MenuItem的点击事件:
<MenuItem onClick={() => { handleCloseMenu(); // 执行对应菜单项的滚动逻辑,比如跳转到子章节 }}> <p className="text-sm">Menu Item 1</p> </MenuItem>
内容的提问来源于stack exchange,提问作者Kevin
相关产品推荐
相关产品推荐

