I feel like I'm going insane... So, as per my understanding and seemingly the universal consensus of the internet, mouseout
fires on the cursor leaving an element or any of it's children, whilst mouseleave
only fires on the cursor leaving the element the event is attached to. So I take something as barebones as this:
<html>
<body>
<div id='test'>
<ul>
<li>One</li>
<li>Two</li>
<li>Three</li>
<li>Four</li>
</ul>
</div>
<script>
const div = document.getElementById('test');
div.addEventListener('mouseleave', (e) => console.log('out'), true);
</script>
</body>
</html>
... and the mouseleave
event is definitely still firing when the mouse leaves any of the descendents of that div. I feel like I must be doing something so obviously wrong, but... what?
Try to remove last argument from your addEventListener
- it is called useCapture
and by default its false
. If you pass true
, when event will be fired on capturing phase, which will cause firing mouseleave
on every child element. Read more about useCapture
parameter - https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener
mouseleave
event doesn't bubbles because of that it will not trigger parent event when leaving child element. But when you pass useCapture
- you force event to be fired on capturing phase. Event phases on MDN - https://developer.mozilla.org/ru/docs/Web/API/Event/eventPhase
const div = document.getElementById('test');
div.addEventListener('mouseleave', (e) => console.log('out')); // Remove `true`
<html>
<body>
<div id='test'>
<ul>
<li>One</li>
<li>Two</li>
<li>Three</li>
<li>Four</li>
</ul>
</div>
</body>
</html>