Search code examples
javascripthtmlmouseleavemouseout

MouseLeave behaving like MouseOut?


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?


Solution

  • 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>