javascriptcssdom-eventsonmouseout

Prevent onmouseout when hovering child element of the parent absolute div WITHOUT jQuery


I am having trouble with the onmouseout function in an absolute positoned div. When the mouse hits a child element in the div, the mouseout event fires, but I do not want it to fire until the mouse is out of the parent, absolute div.

How can I prevent the mouseout event from firing when it hits a child element WITHOUT jquery.

I know this has something to do with event bubbling, but I am having no luck on finding out how to work this out.

I found a similar post here: How to disable mouseout events triggered by child elements?

However that solution uses jQuery.


Solution

  • function onMouseOut(event) {
            //this is the original element the event handler was assigned to
            var e = event.toElement || event.relatedTarget;
            if (e.parentNode == this || e == this) {
               return;
            }
        alert('MouseOut');
        // handle mouse event here!
    }
    
    
    
    document.getElementById('parent').addEventListener('mouseout',onMouseOut,true);
    

    I made a quick JsFiddle demo, with all the CSS and HTML needed, check it out...

    EDIT FIXED link for cross-browser support http://jsfiddle.net/RH3tA/9/

    NOTE that this only checks the immediate parent, if the parent div had nested children then you have to somehow traverse through the elements parents looking for the "Orginal element"

    EDIT example for nested children

    EDIT Fixed for hopefully cross-browser

    function makeMouseOutFn(elem){
        var list = traverseChildren(elem);
        return function onMouseOut(event) {
            var e = event.toElement || event.relatedTarget;
            if (!!~list.indexOf(e)) {
                return;
            }
            alert('MouseOut');
            // handle mouse event here!
        };
    }
    
    //using closure to cache all child elements
    var parent = document.getElementById("parent");
    parent.addEventListener('mouseout',makeMouseOutFn(parent),true);
    
    //quick and dirty DFS children traversal, 
    function traverseChildren(elem){
        var children = [];
        var q = [];
        q.push(elem);
        while (q.length > 0) {
          var elem = q.pop();
          children.push(elem);
          pushAll(elem.children);
        }
        function pushAll(elemArray){
          for(var i=0; i < elemArray.length; i++) {
            q.push(elemArray[i]);
          }
        }
        return children;
    }
    

    And a new JSFiddle, EDIT updated link