4

I'm making drop-down sub-menus with jquery, but when I hover over any of the main navigation links, all of the sub-menus drop down. I believe I need to do something with this() but I can't seem to get the syntax right. Here's a fiddle http://jsfiddle.net/xzN5G/

Here's my HTML

<nav id="nav">
    <ul class="nav">
        <li class="mainli"><a href="" class="selected">Home</a>
            <ul class="submenu">
                <li>s1111111</li>
                <li>a2222222</li>
                <li>g3333333</li>
                <li>y4444444</li>
            </ul>
        </li>    
        <li class="mainli"><a href="album.html">My Photos</a>
            <ul class="submenu">
                <li>11111111</li>
                <li>22222222</li>
                <li>33333333</li>
                <li>44444444</li>
            </ul>
        </li>
        <li class="mainli"><a href="travel.html">My Travel</a>
            <ul class="submenu">
                <li>aaaaaaaaaa</li>
                <li>bbbbbbbbbb</li>
                <li>cccccccccc</li>
                <li>dddddddddd</li>
            </ul>
        </li>
        <li class="mainli"><a href="aboutwork.html">About Work</a>
            <ul class="submenu">
                <li>rgre1111</li>
                <li>estg22</li>
                <li>thser3333</li>
                <li>rtyr4444</li>
            </ul>
        </li>
        <li class="mainli"><a href="portfolio.html">My Portfolio</a>
            <ul class="submenu">
                <li>qqqqqqqq</li>
                <li>tttttttt</li>
                <li>ppppppppp</li>
                <li>yyyyyyyyyy</li>
            </ul>
        </li>
        <li class="mainli"><a href="contact.html">Contact Me</a>
            <ul class="submenu">
                <li>99999999</li>
                <li>88888888</li>
                <li>77777777</li>
                <li>66666666</li>
            </ul>
        </li>
    </ul>
</nav>  

and my jquery

$(document).ready(function(){
    $(".mainli").hover(function() {
        $(".submenu").slideDown("medium");
    }, function () {
        $(".submenu").slideUp("medium");
    })
});
isherwood
  • 58,414
  • 16
  • 114
  • 157
Esser
  • 540
  • 1
  • 4
  • 16

5 Answers5

1

Use the .find() method, and set your .submenu to display: none so it's hidden at first:

$(document).ready(function() {
  $(".mainli").hover(function() {
    $(this).find(".submenu").slideDown("medium");
  },
  function() {
    $(this).find(".submenu").slideUp("medium");
  }
  );
});

See DEMO.

zxqx
  • 5,115
  • 2
  • 20
  • 28
  • Is `find` preferred to `children` in this context? I said `children` in my answer but `find` may be more efficient or handle certain cases better. – akousmata Jan 21 '14 at 20:28
1

There's probably better ways to do this but given minimal changes to your code, the following should work:

$(document).ready(function(){
    $('.submenu').slideUp();
    $(".mainli").hover(function() {
        $(this).children('.submenu').slideDown("medium");
    },
    function () {
        $(this).children('.submenu').slideUp("medium");
    });
});

http://jsfiddle.net/VAYxh/4/

akousmata
  • 1,005
  • 14
  • 34
  • Just one more question. Being that i have content underneath the menus, how do I get that content to ignore the sub-menus dropping down on them? – Esser Jan 21 '14 at 21:16
1

You need to search for the .submenu inside $(this), the method find() will do this for you. children() will work as well in your case, as long as the .submenu is a direct child of this(). find() on the other hand searches within all descendants (aka children, grandchildren etc..)

According to What is fastest children() or find() in jQuery? there's no great deal of difference in terms of speed between both functions

$(document).ready(function () {
    // $(".submenu").slideUp("medium");
    $(".mainli").hover(function () {
        $(this).find(".submenu").slideDown("medium");
    },

    function () {
        $(this).find(".submenu").slideUp("medium");
    });
});

I tried this out in your fiddle and it worked, you might want to uncomment that line $(".submenu").slideUp("medium"); so that all menus start closed.

Community
  • 1
  • 1
Mohamed Khamis
  • 7,731
  • 10
  • 38
  • 58
  • I don't think it's ideal to hide the `.submenu` with JS like that. It's likely to cause a flash of the visible menu while the page is loading. – zxqx Jan 21 '14 at 20:30
  • Thanks. If you add a fiddle it will always be more appreciated. – Esser Jan 21 '14 at 20:31
0

http://jsfiddle.net/xzN5G/4/

$(".submenu", this)

That should do it for you. Also, in your CSS, you need to have .submenu { display: none; }

Dudo
  • 4,002
  • 8
  • 32
  • 57
0

I would personally hide the sub-menus by default and then check if they are hidden on hover, if they are hidden then slide them down otherwise just use hide.

See this fiddle.

Updated JS.

$(document).ready(function () {
    $(".mainli").hover(function () {
        var target = $(this).find('.submenu');
        if (target.is(':hidden')) {
            target.slideDown("medium");
        } else {
            target.hide();
        }
    });
});

Added CSS

ul.submenu {
    float: right;
    display:none;
    overflow:hidden;
}
Kyle Needham
  • 3,379
  • 2
  • 24
  • 38