Mouse leave workaround

by bgil2012

HTML

<div id="target1" class="target">target 1</div>
<div id="target2" class="target">target 2</div>
<div id="target3" class="target">target 3</div>
<div id="target4" class="target">target 4</div>
<div id="hoverReport">NONE</div>

CSS

.target{
    background-color:#3366FF;
    /*margin-top:10px;*/
    width:10em;
    height:50px;
    border:1px solid red;
}

JavaScript

/* Response to Stackoverflow question: http://stackoverflow.com/questions/7448468/why-cant-i-reliably-capture-a-mouseout-event/11605329#11605329
 *
 * Javascript can miss the mouseleave event so need to manage this
 * state myself.
 */
var NO_TARGET = 'none';
var targetCalloutId = NO_TARGET;
var inMouseEnterProcessing = false;

$(document).mousemove(function(e) {
    if (targetCalloutId == NO_TARGET) {
        return;
    }
    if (inMouseEnterProcessing) {
        return;
    }
    var targetId = e.target.id;
    if (targetCalloutId == targetId) {
        return;
    }
    var parents = $(e.target).parents("*");
    for (var i = parents.length - 1; i >= 0; i--) {
        var parent = parents[i];
        if (targetCalloutId == parent.id) {
            //console.log('mouse over parent ' + targetCalloutId);
            return;
        }
    }
    // DO THE MOUSE OUT EVENT PROCESSING
    $('#hoverReport').text("");
    // RESET THE TARGET ID
    targetCalloutId = NO_TARGET;
});


var mouseEntersHoverZone = function(eventObject) {
    // javascript seems to call the mouse enter event more than once.
    if (inMouseEnterProcessing) return;
    inMouseEnterProcessing = true;
    // SET THE TARGET ID FOR MOUSE OUT EVENT DETECTION
    var targetId = eventObject.target.id;
    targetCalloutId = targetId;
    // DO THE MOUSE ENTER EVENT PROCESSING
    $('#hoverReport').text(targetCalloutId);
    // CLEAR THE FLAG THAT INDICATES MOUSE MOVE EVENTS ARE IN THE
    // MOUSE ENTER EVENT PROCESSING
    inMouseEnterProcessing = false;
}

    $(document).ready(function() {
elems = $('.target');
jQuery.each(elems, function(index, elem) {
    $(elem).bind('mouseenter', null, mouseEntersHoverZone);
});
});