Halcyon
Halcyon

Reputation: 14971

Trouble Emulating A Simple Menu Using jQuery

I have 2 div tags which emulate a drop-down menu. When the outer div is clicked, the inner div shows below it with some links. I want the inner div to hide itself only when the mouse has left either div.

Here is how the code is failing:

  1. Click the outer div.
  2. Do not enter the inner div.
  3. Move the mouse up, left or right to leave the outer div. The inner div should hide itself, but doesn't.

I understand that I need to have a mouseout event hooked to the outer div, but when I do that, it hides the inner div when I try to enter it.

How can I get the inner div to hide itself when the mouse leaves either div?

<style type="text/css">
    div.toggleMenu { position: relative; }
    div.menu { position: absolute; left: -3px; top: 19px; display: none; }
</style>
<div class="toggleMenu">
    Toggle Menu
    <div class="menu">
        <ul>
            <a href="http://www.google.com/"><li>Google</li></a>
            <a href="http://www.yahoo.com/"><li>Yahoo</li></a>
            <a href="http://www.bing.com/"><li>Bing</li></a>
        </ul>
    </div>
</div>
<script type="text/javascript">
    // Toggle the menu.
    $('.toggleMenu').click(function ()
    {
        $(this).find('.menu').toggle();
    });

    // Hide the menu when the mouse leaves the tag.
    $('.menu').mouseleave(function ()
    {
        $(this).hide();
    });
</script>

Update: Part of my problem with the inner div disappearing when I tried to mouseover it was due to line-height issues my code was having. After closer examination (1600x zoom in IE) I found my issue and I now have jquery set the height programmatically. Here is the final code for those interested:

$('.toggleMenu').click(function ()
{
    if ($(this).find('.menu').css('display') == 'none')
    {
        // The menu needs to be positioned programmatically for the
        // height due to the differences among browser interpretations of height.
        var height = $('.toggleMenu').height() - 1;
        $(this).find('.menu').css('top', height + 'px');
        $(this).find('.menu').css('left', '-3px');
        $(this).find('.menu').show();
    }
    else
    {
        $(this).find('.menu').hide();
    }
});

// Hide the menu when the mouse leaves the tag.
$('.toggleMenu').mouseleave(function ()
{
    $(this).find('.menu').hide();
});

Upvotes: 0

Views: 244

Answers (3)

shaneburgess
shaneburgess

Reputation: 15882

I would try: http://jsfiddle.net/shaneburgess/k5WRG/1/

  // Toggle the menu.
    $('.toggleMenu').click(function ()
    {
        $(this).find('.menu').toggle();
    });

    // Hide the menu when the mouse leaves the tag.
    $('.toggleMenu').mouseleave(function ()
    {
        $(this).find(".menu").hide();
    });

Upvotes: 1

ayyp
ayyp

Reputation: 6598

Here's the code you need:



    $(".toggleMenu").live({
      click: function() {
        $(this).find('.menu').show();
      },
      mouseleave: function() {
        $(this).find('.menu').hide();
      }
    });

Because you were using the toggle function, it wouldn't hide again unless you clicked again. Here it is on JSFiddle http://jsfiddle.net/Skooljester/9Dfjr/10/

Update: You can shorten the $(this).find('.menu').show(); line to $('.menu').show();, which goes for the .hide(); line as well.

Upvotes: 0

SeanCannon
SeanCannon

Reputation: 77966

Since .menu is a child of .toggleMenu you can simply assign the mouseleave() event to the parent and it will affect both. This is the primary benefit of using mouseleave() versus mouseout().

$('.toggleMenu').mouseleave(function ()
{
    $(this).children('.menu').hide();
});

Working demo: http://jsfiddle.net/AlienWebguy/hNT6P/

Upvotes: 0

Related Questions