Or Weinberger
Or Weinberger

Reputation: 7472

Finding children of element without an id or class

I have the following code structure:

<ul class='menu'>
    <li>
         Main Menu
         <ul class='hide'>
             <li>SubMenu1</li>
             <li>SubMenu2</li>
         </ul>
    </li>
    <li>
         Main2
         <ul class='hide'>
             <li>Sub1</li>
         </ul>
    </li>
</ul>

Is there a way for me to have a jQuery click event on Main Menu and Main2 in a generic way that will remove the class 'hide' of the correct children each time?

Upvotes: 1

Views: 157

Answers (4)

Filip Ros&#233;en
Filip Ros&#233;en

Reputation: 63797

Dont always do what the crowd tells you, at least think about it for a while!

I bet people will recommend you to use a selector such as ul.menu > li, but please remember that this will not only trigger a click event when you click on the text "Main Menu", but also when you click on any of the other content inside the matching li.

If you'd like to implement a show/hide toggle you are far better off wrapping the text "Main Menu" inside it's on element, and then use something as the below to alter what you may want to alter.

$(<main menu text selector>).siblings (<siblings selector>);

Still want/have to follow the crowd?

If this is the case I'd recommend you to at least do it with a little twist to prevent what I previously described.

(edit: revised version after reading the jquery documentation for elements)

$('ul.menu > li').click (function(e){
  if (e.target === this) {
    $(this).children ('.hide').removeClass ('hide');
  }
});

$("ul.menu > li").click (function () {
  $(this).find ('.hide').removeClass ('hide'); 
});

$("ul.menu > li > *").click (function () {
   return false; // prevent event from bubbling up 
});


Sample implementation of recommended version

The below will bind a click-event-listener to .menu-toggle, when the event is fired the siblings (ie. the tags who are in the same scope as the clicked .menu-toggle) matching .hide will have their class="hide" removed.

Javascript

$(".menu-toggle").click (function () {
  $(this).siblings ('.hide').removeClass ('hide'); 
});

HTML

<ul class='menu'>
    <li>
        <span class="menu-toggle">Main Menu</span>
         <ul class='hide'>
             <li>SubMenu1</li>
             <li>SubMenu2</li>
         </ul>
    </li>
    <li>
         <span class="menu-toggle">Main2</span>
         <ul class='hide'>
             <li>Sub1</li>
         </ul>
    </li> </ul> 

Upvotes: 2

Felix Kling
Felix Kling

Reputation: 816324

Here is another way, which uses event delegation and only runs when the li element and not its children was clicked:

$('ul.menu').on('click', 'ul.menu > li', function(e) {
    if(e.target === this) {
        $(this).children('ul').toggleClass('hide');
    }
});

DEMO

Upvotes: 3

user60456
user60456

Reputation:

Take a look at the child selectors. I think that is what you want.

$('.menu > li').click(function () { 
    $(this).children('ul').removeClass('hidden'); 
}); 

Upvotes: 0

Andrew Whitaker
Andrew Whitaker

Reputation: 126042

$("ul.menu > li").on("click", function () {
    $(this).children("ul").removeClass("hide");
});

Example: http://jsfiddle.net/dpkBL/

Upvotes: 2

Related Questions