Do Not Hide Element When Hovered

283 views Asked by At

I have an element that needs to slideDown when another element is hovered over, and remain visible when it is hovered over itself. Due to issues involving a design with a lot of overlapping elements and heavy use of z-index, I cannot nest the sliding element inside the hovered over element; they cannot even be siblings.

The HTML:

<div class="a">
    <div class="b">
        <div class="c">
            <nav class="navvy">
                <ul>
                    <li class="active">
                        <a href="#" class="one">One</a>
                    </li>
                    <li>
                        <a href="#" class="two">Two</a>
                    </li>
                </ul>
            </nav><!--nav-1-->
        </div><!--c-->
    </div><!--b-->
</div><!--a-->
<div class="slidedown slidedown-one">
    <div class="slide-content">
        One - text.
    </div><!--slide-content-->
</div><!--slidedown-->
<div class="slidedown slidedown-two">
    <div class="slide-content">
        Two - text.
    </div><!--slide-content-->
</div><!--slidedown-->

The jQuery (note: I'm using the hoverIntent plugin):

//Hide all slidedown divs
$('.slidedown').hide();

//Find the active class
var activeCl = $('.navvy').children('ul').find('.active').children('a').attr('class').split(' ')[0];

//Slide it down
var downSlide = function() {
    activeCl = $(this).attr('class').split(' ')[0];
    $('.slidedown-'+activeCl).slideDown(1000);
};

//Slide it up
var upSlide = function() {
    activeCl = $(this).attr('class').split(' ')[0];
    $('.slidedown-'+activeCl).delay(1000).slideUp(1000);
};

//Slide on hover
var slideHover = function() {
    $('.navvy').children('ul').find('li').children('a').hoverIntent({
        over: downSlide,
        out: upSlide
    });
};
slideHover();

It slides up and down fine, but I need it to not slide back up again when the mouse is inside of the div that slid down.

EDIT: Here is a JSFiddle with the code: http://jsfiddle.net/qeLVU/2/

2

There are 2 answers

2
MattDiamant On

Your code looks like you're over thinking this a bit. Just slide down or up when you hover on or off the nav link, and the same with the div itself.

$('.nav-1 ul li a').hover(function () {
    $('.slidedown-' + this.className).stop().slideDown();
}, function (){
    $('.slidedown-' + this.className).stop().slideUp();
});

$('.slidedown').hover(function () {
    $(this).stop().slideDown();
}, function (){
    $(this).stop().slideUp();
});

http://jsfiddle.net/cJWn8/

5
FiLeVeR10 On

using hoverIntent

On your hoverIntent, it doesn't know it should also work on the content, you need to let it know what you want. $('.navvy').children('ul').find('li').children('a').hoverIntent would need to be more like $('.navvy li').hoverIntent with the slide content inside of the li so that they're both triggering the hover events.

so the html would be more like:

<nav class="navvy">
    <ul>
        <li>
            <a href="#">Home</a>
            <div>One - text.</div>
        </li>
        <li>
            <a href="#">About</a>
            <div>Two - text.</div>
        </li>
    </ul>
</nav>

Then the jquery becomes much easier, and you can do something like:

$('.navvy li').hoverIntent({//on common parent
    over: function() {
        $(this).addClass('active')//add active
        .children('div').stop(true,true).slideDown('slow');//slide down
    },
    out: function() {
        $(this).removeClass('active')//remove active
        .children('div').stop(true).slideUp('fast');//slide up
    }
});

made a fiddle: http://jsfiddle.net/filever10/TCY78/

jquery without intent or changing html

If you are unable to change the html in this instance, or don't wish to rearrange it, then something like this will work on the existing html.

$('.navvy a').each(function(i) {//i gives you the index of the element
    var cl = $(this),//current link
        cc = $('.slidedown').eq(i),//current content
        dl = 0,//initial delay
        spd = 500,//speed
        tim = 250;//timeout
    cl.add(cc).hover(function() {//hover on
        !$('.slidedown:visible').length?dl=0:dl=spd;//set delay
        clearTimeout(cl.data('timer'));//clear timer
        cl.parent('li').addClass('active');//active on 
        cc.stop(true,true).delay(dl).slideDown(spd);//slide down
    }, function() {//hover off
        cl.parent('li').removeClass('active');//active off
        var timer = setTimeout(function() {//timeout
            cc.stop(true).slideUp(spd);//slide up
        }, tim);//delay
        cl.data('timer', timer);//set timer
    });
});

made a fiddle: http://jsfiddle.net/filever10/xn85z/