HTML Nested Elements & OnMouseOut Event

By Akbar

If you are trying to track the mouse-out event, for example to hide the sub menu when user leave that area, then there are good chances there are good chances that you may stuck into a problem, where the parent element mouse-out event fires, when you move the cursor to the child.

Here is a quick demo of this:

You will notice that as soon as you move the mouse over to the child DIV, the mouse out event of the parent is fired. This is problem in most of the cases, where you want to detect the true mouse out (where the mouse is still over main Div or any of its child Div areas).

There are two possible solutions for this. First is that if you are using the JQuery, then you are good. There is already a special event in JQuery called mouseleave which does exactly what you want. All you have to do is to bind to this event instead of HTML element onmouseout event, and you are good.

However, if you are not using the JQuery, and for some reason don’t want to use it just for this fix. Then there is simple JavaScript only fix for this too (somewhat same rule is used by JQuery too). Here is the JavaScript for such mouse leave event:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
 
// JQuery style getElementByID wrapper
$ = function(id) {
    return document.getElementById(id);
}
 
// Our generic code to handle the on mouse event
isMouseLeave = function(event, parent) {
    // Get the reference to the event object
    if (!event) var e = window.event;
 
    // Get the target parent (extra code for cross browser compatability)
    e = event.toElement || event.relatedTarget;
 
    // Now keep traversing all the parents of the current target object to detect if the
    // object on which the mouse is being moved is child of the main parent element we are looking
    // for or not
    while (e && e.nodeName && e.nodeName != 'BODY') {
        // if this is a child element, ignore this on mouse out event
        if (e == parent) return false;
 
        // check the next parent
        e = e.parentNode;
    };
 
    // If we are here, then this is actually the mouse out leave event, so do what you want to do
    return true;
}
 
// Generic event binder
bindMouseOut = function(object, handler) {
    object.onmouseout = function(event) {
 
        // Call handler if this is mouse leave even
        if (isMouseLeave(event, object))
            handler();
    };
}

And you can bind this mouse leave function with any HTML element using the following simple script:

1
2
3
4
5
 
bindMouseOut ($('outerDiv'), function(){
       showMsg('messageLog', 'Out Div Mouse Out');
})

You can view this in action on Jfiddle:

JQuery magic revealed.

Tags: , , ,