Search code examples
javascriptjqueryjquery-animatejquery-hoverhoverintent

How can I apply the same jQuery hover animation to two divs of different height side-by-side?


I have a menu <div> with a shorter handle <div> to the right of it (see below). This loads off to the left of the screen minus a 5px sliver of the menu <div> and the whole handle <div>. I want the whole container to slide onto the screen when the mouse hovers either portion, and off the screen when it leaves both portions.

This works except when the mouse goes from the handle to the menu. There is a brief moment where the mouseleave from the handle and the mouseenter from the menu fire. I have tried to .stop(true) the current animation on the container, but there is still a hesitation in the animation.

Menu Sample

#slideout-nav contains both elements (and transparent space below the handle, which I do not want to trigger the animation).
#slideout-menu-container is the left portion.
#slideout-handle is the right portion.

$('#slideout-menu-container').addClass('slideout-hover');
$('#slideout-handle').addClass('slideout-hover');

var slideIn = function () {
    $('#slideout-nav').stop(true);
    $('#slideout-nav').animate({
        left: '0px'
    });
};

var slideOut = function () {
    $('#slideout-nav').stop(true);
    $('#slideout-nav').animate({
        left: distance * -1 + 'px'
    });
};

$('.slideout-hover').hoverIntent(slideIn, slideOut);

Is there a more elegant way to accomplish this?

Update

HTML:

<div id="slideout-nav">
    <div id="slideout-handle">+</div>
    <div id="slideout-menu-container">
        <ul>
            <li><a>Home</a></li>
            <li><a>Models</a></li>
        </ul>
    </div>
</div>

CSS:

#slideout-nav {
    z-index: 99;
    position: absolute;
    top: 0;
    width: 225px;
}

#slideout-handle {
    float: right;
    padding: 10px;
    background: rgba(0, 0, 0, 0.8);
}

#slideout-menu-container {
    overflow: hidden;
    background: rgba(0, 0, 0, 0.8);
    padding: 10px;
}

Solution

  • I came up with a solution to this based on an answer to another question.

    I set the containing <div> to have a height and width of 0 with overflow: visible. Then I gave the containing <div> the hover event. This ensures that the event is only triggered when the mouse enters or leaves its children (my menu and handle <div>s).

    Here is a JSFiddle for posterity.

    HTML:

    <div id="container">
        <div id="menu">Menu</div>
        <div id="handle">+</div>
    </div>
    

    JS:

    var slideIn = function () {
        $('#container').stop(true);
        $('#container').animate({
            left: '0px'
        }, 'fast');
    };
    
    var slideOut = function () {
        $('#container').stop(true);
        $('#container').animate({
            left: '-190px'
        }, 'fast');
    };
    
    
    $('#container').hover(slideIn, slideOut);
    

    CSS:

    #container {
        width:0;
        height:0;
        overflow:visible;
        position:absolute;
        left:-190px;
    }
    
    #handle {
        padding:10px;
        width:auto;
        height:auto;
        background: rgba(0, 0, 0, 0.8);
        font-size:18px;
        color:#FFF;
        display:inline-block;
        border-bottom-right-radius:3px;
    
    }
    
    #menu {
        background: rgba(0, 0, 0, 0.8);
        width:195px;
        height:300px;
        float:left;
        display:inline-block;
        border-bottom-right-radius:3px;
    }