'How to prevent svg on top of other div of triggering mouseleave
I have an issue with mouseleave
. (React/Typescript/CSS/HTML project).
Situation
(see picture at the bottom)
I got two div
elements
<>
<div id="main">
<div>
<div id="onHover" style={{display: "none"}}>
</div>
</>
and I got an svg
on top of div main
.
return(
<svg className="click-through" pointer-events="none" width={1560} height={262}>
<VictoryChart
style={{
parent: { pointerEvents: 'none' }
}}
>
<VictoryArea
style={{
parent: { border: '1px solid #ccc', pointerEvents: 'none' }
}}
/>
</VictoryChart>
</svg>
)
Goal:
- Upon hovering over
div main
,div onHover
should be displayed next todiv main
- Upon leaving
div main
,div onHover
should disappear again.
The first goal is no issue, the second one is: Because of the svg
, mouseleave
is triggered too early.
The whole situation as a picture (The dotted white lines are from the svg
which trigger mouseleave
, the blue box would be div main
):
For other reasons, the svg
can't go behind div main
.
How can I make sure now that svg
lines don't trigger mouseleave
?
Further Information
- For the
svg
I'm usingvictory js
to display graphs - That
svg
has the propertyclick through
andpointer-events: none
- This situation is heavily simplified but explains my key problem
Solution 1:[1]
Did you try to add pointer-events: none;
to that SVG? Here is an example (green box does not fire any event but the blue one does):
const wrap = document.querySelector('.mouseleave');
wrap.addEventListener('mouseleave', () => {
console.log(".mouseleave left");
});
.wrap {
position: relative;
}
.mouseleave {
height: 200px;
border: 2px solid red;
}
.p-none, .p-default {
height: calc(100% - 2rem);
position: absolute;
top: 1rem;
}
.p-none {
pointer-events: none;
border: 2px solid green;
left: 1rem;
}
.p-default {
border: 2px solid cyan;
right: 1rem;
}
<div class="wrap">
<div class="mouseleave"></div>
<div class="p-none">pointer events: none</div>
<div class="p-default">pointer events: default</div>
</div>
Solution 2:[2]
the pointer-events: none
property needs to be set in css
but the more modern(and very performant) way is to use a PointerEvent instead of MouseEvent and bind the event to the desired element.. that way all other element listeners dont fire at all..
element.setPointerCapture(ev.pointerId)
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Jax-p |
Solution 2 | zergski |