Cuty Pie
Cuty Pie

Reputation: 65

document.click keep toggling the menu

I have this simple header menu but when i click #nav li ,the #nav ul keeps toggling.I want to hide #nav ul if clicked anwhere else on the document.

   $(document).ready(function() {
      $('#nav li').click(function() {
      $('ul', this).show('fast');
    });

     $(document).click(function() {
        $('ul','#nav li' ).hide('fast');

    });

  });

Here is the Simpe HTML. http://jsfiddle.net/pMaL5/

 <div id="nav">

    <li style="margin-top: -15">
        <a class="modalbox"  href="#header2_li" style="font-size: 40px;">ADD</a>
        <ul>
        <li>
            <a class="modalbox" href="#inlineheadersend">Settings</a>
        </li>
        <li>
            <a>News</a>
        </li>
    </ul>
    </li>

    <li>
        <span href="#">Messages</span>
        <ul>
            <li>
                <a class="modalbox" href="#inlineheadersend">compose new</a>
            </li>
            <li>
                <a>show messages</a>
            </li>
        </ul>

        <div class="clear"></div>
    </li>


</div>

Upvotes: 1

Views: 128

Answers (3)

A. Wolff
A. Wolff

Reputation: 74420

This is an other way, without binding anything to document:

$(document).ready(function() {
    $('#nav').click(function() {
        $('.showhide').show('fast').focus();
    });

    $('.showhide').focusout(function(e) {
         $(this).hide('fast');
    }).focus();
});​

See DEMO based on Juan Mendes answer

Upvotes: 1

Ruan Mendes
Ruan Mendes

Reputation: 92274

The problem is what pimvdb mentioned. Every click propagates to the document (unless you call stopPropagation()).

The problem with pimvdb mentioned (calling stopPropagation) is that there may be other handlers relying on your clicks going all the way to the document. Which is what it looks like is happening with fancybox

I've modified your HTML to make more sense and be simpler to read. Your previous HTML was setting handler on all lis but it should only be doing it to the first one. I added some class names to make your HTML more semantic, relying on tag names is poor practice

<div id="nav">
  <ul>
    <li class="add"><a class="modalbox">ADD</a></li>     
    <li>
        <span href="#">Messages</span>
        <ul class="showhide">
            <li><a class="modalbox" href="#inlineheadersend">compose new</a></li>
            <li><a>show messages</a></li>
        </ul>
        <div class="clear"></div>
    </li>
   </ul>
</div>​

http://jsfiddle.net/8s6wJ/1/

The following script does what you need to the above HTML without preventing the click from propagating.

$(document).ready(function() {
    $('#nav').click(function() {
        $('.showhide').show('fast');
    });

     $(document).click(function(e) {
         // Only hide if actual element clicked 
         // was not a child of #nav
         if ($(e.target).closest('#nav').length == 0) {
             $('.showhide').hide('fast');
         }
    });
});​

Upvotes: 2

pimvdb
pimvdb

Reputation: 154818

Events bubble up, so when you click a li, you implicitly also click the document (because document is a ancestor of the li). You can prevent that with e.stopPropagation():

$('#nav li').click(function(e) {
  e.stopPropagation();

Upvotes: 3

Related Questions