Вопрос

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;
}
Это было полезно?

Решение 2

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;
}

Другие советы

Ok, I think I got you problem. I made some changes in your css (maybe it just fits the jsFiddle needs) :

#slideout-nav {
    z-index: 99;
    position: absolute;
    top: 0;
    left: -200px; /* Here */
    width: 225px;
}

And in the JS :

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

var isAnimated = false;
var mouserOverHandle = false;

var slideIn = function () {
    if (!isAnimated) {
        isAnimated = true;
        $('#slideout-nav').animate({
            left: '0px'
        }, function () {isAnimated = false;});
    }
};

var slideOut = function () {
    setTimeout(function () {
        if (!isAnimated && !mouseOverHandle) {
            isAnimated = true;
            $('#slideout-nav').animate({
                left: '-200px'
            }, function () {isAnimated = false;});
        }
    }, 10);
};

$('#slideout-handle').hover(function () {mouseOverHandle = true;}, function () {mouseOverHandle = false;});
$('.slideout-hover').hover(slideIn, slideOut);

I added a lock (isAnimated) to prevent the menu from sliding in other direction when it is already sliding.

And, the tricky part I think it can be improved, I added a timer to the slideOut function, because we have to know (when leaving the menu-container div) if we are over the handle or no. So the timer is just here to "wait" the event hover over the handle to be fired.

Without the timer (and the mouseOverHandle var) the menu slides out when your mouse goes over the handle from the menu-container. Feel free to remove it if it is not a matter for you.

See the jsFiddle here.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top