-1

I currently have an <a> witin an <li> which when clicked, opens a sub menu.

I now want to make it so that is you click that <a> when it's parent has a class of .open, it closes. But it won't fire.

The HTML:

<li class="menu-item-has-children open">
    <a href="#">emerging market</a>
    <ul class="sub-menu">
        [sub menu stuff]
    </ul>
</li>

So when you click .open a, it should first hide the sibling ul .sub-menu and then removeClass open from the parent

The jQuery

jQuery(".open a").click(
    function (){
        console.log('here!'); // this never seems to fire
        jQuery(this).sibling(".sub-menu").hide();
        jQuery(this).parent().removeClass("open");
});

JS Fiddle showing the (working) opening function but the non-working closing function

http://jsfiddle.net/aa5brt5v/

Francesca
  • 26,842
  • 28
  • 90
  • 153
  • 1
    Is your jQuery in a document.ready call or at the end of the document? It works for me: http://jsfiddle.net/j08691/70jryhj1/ (BTW it's `siblings` (plural), not `sibling`). – j08691 Jan 14 '15 at 16:13

3 Answers3

4

Why don't use just simply toggle the child list?

$(".menu-item-has-children").click(function() {
  $(this).find(".sub-menu").toggle();
});
/* Default is to hide sub menu */
ul.sub-menu {
  display: none;
  background-color: orange;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<li class="menu-item-has-children"> <a href="#">emerging market</a>
  <ul class="sub-menu">
    <li>[sub menu stuff]</li>
  </ul>
</li>
j08691
  • 204,283
  • 31
  • 260
  • 272
  • 1
    Very elegant solution. – Rory McCrossan Jan 14 '15 at 16:22
  • This makes a lot more sense, classic overthinking! The problem I am having is that the `find` seems to be targeting incorrectly. There are actually sub-sub menus. Here is a fiddle to explain: http://jsfiddle.net/aa5brt5v/3/ – Francesca Jan 14 '15 at 16:36
  • 1
    Are you looking for something more line this: http://jsfiddle.net/j08691/ct5vcohs/? – j08691 Jan 14 '15 at 16:42
2

The issue is because the events are assigned on DOMReady. At that time there are no .open elements as you are adding that class on click of the element, which is well after DOMReady has fired. Instead you could use a single click event on the element. You also can tidy up your logic and DOM traversal a little too, try this:

$(".menu-item-has-children").click(function () {
    if ($(this).hasClass('open')) {
        $(this).removeClass("open").find(".sub-menu").hide();
    } else {
        $(this).addClass("open").find(".sub-menu").show();
    }
});

Updated fiddle

Rory McCrossan
  • 331,213
  • 40
  • 305
  • 339
1

Try using this (Event delegation):

$( ".menu-item-has-children a" ).on( "click", ".open", function() {
 console.log('here!'); 
});
Mark
  • 4,773
  • 8
  • 53
  • 91