ansiart
ansiart

Reputation: 2591

mouseenter mouseleave do not correctly fire on sibling elements

I have 3 elements, that are all siblings, yet they are positioned over each other. I wanted to use mouseenter/mouseleave on these, however, they do not work as expected. (only the topmost element is firing the mouseenter/mouseleave). Is there a native jQuery method to deal with siblings elements? I would like to stay away from checking every element bound on every single mousemove event.

----------- OUTER ELEMENT --------------
|                                      |
|  -------  -------                    |
|  |  A  |  |  B  |                    |
|  -------  -------                    |
|                                      |
----------- OUTER ELEMENT --------------

defined as html:

<div class="outerelement"></div><!-- position absolute, etc -->
<div class="a"></div><!-- position absolute, etc -->
<div class="b"></div><!-- position absolute, etc -->

javascript:

$('div').on('mouseenter mouseleave', function(e) {
    switch (e.type) {
       case 'mouseenter':
         $(this).addClass('hover');
         break;
       case 'mouseleave':
         $(this).removeClass('hover');
         break;
    }
});

jsFiddle here

What ends up happening is mouseenter/leave fires when over A/B correctly, but it should fire for the outer element, however it is not ....

Upvotes: 1

Views: 1528

Answers (1)

ansiart
ansiart

Reputation: 2591

tested with win-chrome only.

<!DOCTYPE html>
<html>
<head>
<style type="text/css">

    * {
        box-sizing: border-box;
    }

    div.overlay div {
        position:       absolute;
        border:         1px solid rgba(0,0,0,0.25);
        height:         100px;
        z-index:        10;
    }

    div.overlay div.hover {
        background-color:   rgba(0,0,0,0.25);
    }

</style>
<script src="js/jquery-2.0.2.min.js"></script>
<script type="text/javascript">
    $(document).on('ready', function(e) {

        var body    = $(this); //.find('body');
        var proxy   = $(this).find('div.overlay');

        var numChildren = 50;
        while (--numChildren) {
            proxy.append(
                $('<div/>').css({
                    'top':  Math.random() * 800,
                    'width':    Math.random() * 800,
                    'height':   Math.random() * 800,
                    'left': Math.random() * 800
                })
            );
        }

        body.on('mousemove', function(e) {

            var children    = proxy.children();
        var x           = e.pageX - window.scrollX;
        var y           = e.pageY - window.scrollY;
            for (var i = 0; i < children.length; ++i) {
                var element = $(children[i]);
                var rect    = element[0].getBoundingClientRect();
                if (rect.contains(x, y)) {
                    if (!element.hasClass('hover')) {
                        element.addClass('hover');
                        element.triggerHandler('truemouseenter');
                    }
                } else {
                    if (element.hasClass('hover')) {
                        element.removeClass('hover');
                        element.triggerHandler('truemouseleave');
                    }
                }
            }
        });

        ClientRect.prototype.contains = function(x, y) {
            return (x >= this.left && x <= this.right && y >= this.top && y<= this.bottom);
        }

    });
</script>
</head>
<body>

    <div class="overlay"></div>

</body>
</html>

Upvotes: 0

Related Questions