在 react-konva 中使用 onMouseOver 将鼠标悬停在元素顶部的图标上
Hovering over icons on top of an element with onMouseOver in react-konva
我有一个 <Group/>
元素,其中包含一个矩形和组顶部的一组图标,只有当用户将光标移动到该 <Group/>
的边界内时,这些图标才应该可见内容。是否显示图标由附加到 <Group/>
对象的 onMouseOver
和 onMouseOut
事件处理程序触发。我使用 useState
挂钩来保存悬停状态和 hide/show 图标。
显示图标 onMouseOver
效果很好。但是只要鼠标光标悬停在图标上,就会触发 <Group/>
的 onMouseOut
事件,从而隐藏图标。将鼠标快速连续移动到一个图标上 shows/hides(闪烁)。
有没有办法强制 <Group/>
到 而不是 触发 onMouseOut
事件,如果光标实际上仍然在它的区域内但在一个图标(事件冒泡?)?
可以解决此问题,方法是使用 React.useRef()
在元素更改时存储元素的悬停状态,并使用延迟函数中的引用来决定要做什么。本质上是这样的:
设置状态、引用和更新引用:
...
const [isGroupHover, setIsGroupHover] = useState(false);
const [isContextMenuHover, setIsContextMenuHover] = useState(false);
const isContextMenuHovereRef = useRef(isContextMenuHover);
const isGroupHoverRef = useRef(isGroupHover);
useEffect(() => {
isContextMenuHovereRef.current = isContextMenuHover;
isGroupHoverRef.current = isGroupHover;
}, [isGroupHover, isContextMenuHover]);
...
拦截 <Group/>
的 onMouseOut
事件
...
const onMouseOut = (e): void => {
setTimeout(() => {
if (!isContextMenuHovereRef.current) {
setIsGroupHover(false);
}
}, 350);
};
...
一个函数(setIsContextMenuHover()
)通过 prop 传递给上下文菜单组件。这样,上下文菜单可以向上传递它自己的悬停状态。
...
<ContextMenu setOnHover={setIsContextMenuHover} />
...
本质上,如果上下文菜单仍然可见或悬停在上方,这可以防止 <Group/>
的悬停状态发生变化。有点笨拙 - 但它有效。
如果你的图标不是交互式的,你不需要为它们监听事件,你可以设置listening = false
。
在这种情况下,一个节点将从命中图中移除并且不会触发mouseenter
。
我有一个 <Group/>
元素,其中包含一个矩形和组顶部的一组图标,只有当用户将光标移动到该 <Group/>
的边界内时,这些图标才应该可见内容。是否显示图标由附加到 <Group/>
对象的 onMouseOver
和 onMouseOut
事件处理程序触发。我使用 useState
挂钩来保存悬停状态和 hide/show 图标。
显示图标 onMouseOver
效果很好。但是只要鼠标光标悬停在图标上,就会触发 <Group/>
的 onMouseOut
事件,从而隐藏图标。将鼠标快速连续移动到一个图标上 shows/hides(闪烁)。
有没有办法强制 <Group/>
到 而不是 触发 onMouseOut
事件,如果光标实际上仍然在它的区域内但在一个图标(事件冒泡?)?
可以解决此问题,方法是使用 React.useRef()
在元素更改时存储元素的悬停状态,并使用延迟函数中的引用来决定要做什么。本质上是这样的:
设置状态、引用和更新引用:
...
const [isGroupHover, setIsGroupHover] = useState(false);
const [isContextMenuHover, setIsContextMenuHover] = useState(false);
const isContextMenuHovereRef = useRef(isContextMenuHover);
const isGroupHoverRef = useRef(isGroupHover);
useEffect(() => {
isContextMenuHovereRef.current = isContextMenuHover;
isGroupHoverRef.current = isGroupHover;
}, [isGroupHover, isContextMenuHover]);
...
拦截 <Group/>
的 onMouseOut
事件
...
const onMouseOut = (e): void => {
setTimeout(() => {
if (!isContextMenuHovereRef.current) {
setIsGroupHover(false);
}
}, 350);
};
...
一个函数(setIsContextMenuHover()
)通过 prop 传递给上下文菜单组件。这样,上下文菜单可以向上传递它自己的悬停状态。
...
<ContextMenu setOnHover={setIsContextMenuHover} />
...
本质上,如果上下文菜单仍然可见或悬停在上方,这可以防止 <Group/>
的悬停状态发生变化。有点笨拙 - 但它有效。
如果你的图标不是交互式的,你不需要为它们监听事件,你可以设置listening = false
。
在这种情况下,一个节点将从命中图中移除并且不会触发mouseenter
。