我很难弄清楚这一点。我已经实现了一个Popover组件,其中,当用户将鼠标悬停在“ i”图标上时,将打开一个弹出窗口;当用户将鼠标悬停在该图标上时,它将关闭该弹出窗口。我认为正在发生的事情是,将鼠标悬停在图标上时,会不断调用open和close方法,因此看起来好像从未打开过。
我的组件
export const InfoIconWrapper = styled(InfoIcon)(({ theme }) => ({
color: fade(theme.palette.black, 0.3),
}));
export const GridWrapper = styled(Grid)(({ theme }) => ({
pointerEvents: 'none',
padding: theme.spacing(1),
}));
const DistributionLinePopover = ({ distributionLine }) => {
const [anchorEl, setAnchorEl] = useState(null);
const handlePopoverOpen = event => {
setAnchorEl(event.currentTarget);
};
const handlePopoverClose = () => {
setAnchorEl(null);
};
const open = Boolean(anchorEl);
const mouseOverPopover = 'mouse-over-popover';
return (
<Fragment>
<Typography
aria-owns={open ? mouseOverPopover : undefined}
aria-haspopup="true"
onMouseEnter={handlePopoverOpen}
onMouseOut={handlePopoverClose}
>
<InfoIconWrapper fontSize="small" />
</Typography>
<Popover
id={mouseOverPopover}
open={open}
anchorEl={anchorEl}
anchorOrigin={{
vertical: 'bottom',
horizontal: 'left',
}}
transformOrigin={{
vertical: 'top',
horizontal: 'left',
}}
// onMouseOut={handlePopoverClose}
disableRestoreFocus
>
<GridWrapper container>
...
</GridWrapper>
</Popover>
</Fragment>
);
};
如何修改此代码以使其表现出预期的效果?最初,我尝试将handlePopoverClose传递给popover,但这使得只有当您将鼠标悬停在实际的Popover而不是悬停在“ i”图标上时,弹出菜单才会关闭。
答案 0 :(得分:0)
不要使anchorElem存在作为开放布尔状态值的一部分。实际上,您根本不需要检查anchorElem。处理DOM元素引用时,存在竞争条件的可能性。
我会将setAnchorEl
更改为setOpen
,然后在输入呼叫时将setOpen
更改为true
。您可能希望像一个“ X”按钮那样使用onClick事件处理程序将其设置为false
。从技术上讲,我认为,当新元素呈现在您悬停的元素之上时,底层元素就会触发“鼠标移出”。参见this:
According to the browser logic, the mouse cursor may be only over a single element at any time – the most nested one and top by z-index.
答案 1 :(得分:0)
好,终于找到了解决方法。
在Popover组件中,将其添加为prop:style = {{pointerEvents:'none'}} 并删除onMouseOut。
在InfoIconWrapper组件中,将其作为道具添加到onMouseLeave = {handlePopoverClose}
按预期工作:)