Programmeur
Programmeur

Reputation: 1531

Clickable sub-menu that just appers on hover

I have a "sub-menu" that just appers on :hover. [[ JSFiddle here. ]]

$('.prices').hover(function () {
    $('.sub-menu').fadeIn(150);
}, function () {
    $('.sub-menu').fadeOut(120);
});

Problem #1 ~ When I :hover the main menu and want to click on a sub-menu's link, it disappears.

Problem #2 ~ When the first problem is solved, I will probably have another one: the sub-menu have a lot of links, so the intuitive user behavior (when he wants to go to the last link) is "draw" a triangle and go there, but this will do the sub-menu disappears again. How avoid this? (Illustration below)

enter image description here

Please read: I know that the sub-menu should be inside li element, but this do not work for what I am doing. The jsfiddle is just an example of the real stuff.

Upvotes: 1

Views: 149

Answers (4)

King King
King King

Reputation: 63317

Your problem is because you add the mouseout event handler (the second argument in hover) which will hide the sub menu whenever it's triggered. There is a simple solution is to give a delay of about 100 ms before actually hiding the sub-menu, it's short enough to make no visual difference but it gives the hovering on the submenu a chance to stop the current animation of the submenu (which is delay and the consequent fadeOut). So the code should be added with:

// .prices:hover shows .submenu
$('.prices').hover(function () {
    $('.sub-menu').stop(true,true).fadeIn(150);
}, function () {
    $('.sub-menu').stop(true,true).delay(100).fadeOut(120);
});
//
$('.sub-menu').hover(function(){        
    $(this).stop(true);  
    $(this).fadeIn(0);
}, function(){
    $(this).fadeOut(120);
});

Demo.

NOTE: Your second problem should not be cared too much. Normally, user should move the mouse over the submenu first. Otherwise we won't have any solution unless just let the submenu shown when the mouse is moved out of the Prices menu.

Upvotes: 1

Ian Clark
Ian Clark

Reputation: 9347

Whilst in most cases I would suggest that you resolve your issues such that your sub-menu is an actual child of it's parent, if you really can't get around that, then something like this should work (See fiddle):

var priceTimeout;

function hide_prices() {
    clearTimeout(priceTimeout);
    $(".sub-menu").fadeOut(150);
}

$(".prices").on("mouseenter", function() {
    $(".sub-menu").fadeIn(150);
});

$(".prices").on("mouseleave", function() {
    clearTimeout(priceTimeout);
    priceTimeout = setTimeout(hide_prices, 1000);
});

$(".sub-menu").on("mouseenter", function() {
    clearTimeout(priceTimeout);
});

$(".sub-menu").on("mouseleave", hide_prices);

A couple of things to note:

  1. Because your .sub-menu is not a descendent of .prices then the mouseleave on prices will always fire when you move from one to the other. We get around this problem, and your "triangle" mouse movement problem by setting a timeout after which we clear the sub-menu. If we enter the sub-menu before that point, we clear our timeout so that it's never hidden.

  2. You could shorten this code by using the short-hand .hover() as you were before, but I prefer the clarity of always using the explicit .on() methods.

Upvotes: 2

John Bupit
John Bupit

Reputation: 10618

Since nesting the uls doesn't work for you, here's an alternate solution.

Fade in the menu on hover event of .prices. But fade out only when mouse is left of .sub-menu. This would fix both the problems.

$('.prices').hover(function () {
    $('.sub-menu').fadeIn(150);
});
$('.sub-menu').mouseleave(function () {
    $(this).fadeOut(150);
});

Also, you may want to hide the sub menu after a certain timeout period, if the user doesn't enter the .sub-menu.

Fiddle

Upvotes: 0

Rashmin Javiya
Rashmin Javiya

Reputation: 5222

here is the solution, try this.

http://jsfiddle.net/iamrmin/tQcX9/3/

<ul class="menu">
    <li class="home">
        <a href="#">Home</a>
    </li>
    <li class="contact">
        <a href="#">Contact</a>
    </li>
    <li class="location">
        <a href="#">Location</a>
    </li>
    <li class="prices">
        <a href="#">Prices &raquo;</a>
        <ul class="sub-menu">
    <li>
        <a href="#">Year 2005</a>
    </li>
    <li>
        <a href="#">Year 2006</a>
    </li>
    <li>
        <a href="#">Year 2007</a>
    </li>
    <li>
        <a href="#">Year 2008</a>
    </li>
    <li>
        <a href="#">Year 2009</a>
    </li>
    <li>
        <a href="#">Year 2010</a>
    </li>
    <li>
        <a href="#">Year 2011</a>
    </li>
    <li>
        <a href="#">Year 2012</a>
    </li>
    <li>
        <a href="#">Year 2013</a>
    </li>
    <li>
        <a href="#">Year 2014</a>
    </li>
</ul>
    </li>
    <li class="jobs">
        <a href="#">Jobs</a>
    </li>
</ul>


.sub-menu {
    display: none;
    position: absolute;
    left: 100px;
    background: #F4F4F4;
    list-style: none;
    padding: 10px;
}


a
{
width: 101px;
display: inline-block;
}

Upvotes: 0

Related Questions