flo flo - 2 months ago 5
jQuery Question

Jquery can't use 3 selectors

I'm writing a small script to make a mobile menu.

However I can't get my selectors to work together.

When I have

$('#nav_button, .nav li, .nav li li')
#nav_button and .nav li
works, however when I remove
.nav li
and leave
$('#nav_button, .nav li li')
this sub menu begins to work as well.
I have also tried using
$('#nav_button, .nav li, .sub_menu li li')
with the same results.

Does anyone have an idea why?


var mobileMenu = function () {

var currentPosition = 'closed'
$('#nav_button, .nav li, .nav li li').click(function() {

if (currentPosition == 'closed') {
currentPosition = 'open';
else {
currentPosition = 'closed';


<div id="head">
<div class="container">
<div class="cover"></div>
<a href="#"><h1 class="logo pull-left">C<span class="logo_space">AV</span>O</h1>
</a> <!-- end logo !-->
<div id="nav_button"></div>
<ul class="nav pull-right">
<li><a href="#menu">Menu</a>
<ul class="sub_menu">
<li><a href="#">Starters</a></li>
<li><a href="#">Breakfast and Brunch</a></li>
<li><a href="#">Salads</a></li>
<li><a href="#">Sandwiches and Wraps</a></li>
<li><a href="#">Pasta</a></li>
<li><a href="#">Mains</a></li>
<li><a href="#">Pizza</a></li>
<li><a href="#">About Us</a></li>
<li><a href="#">Contact</a></li>
</div><!-- end container !-->
</div> <!-- end header !-->


Firstly, two of your selectors match the same elements

$('#nav_button, .nav li, .nav li li')

.nav li matches any LI inside .nav, including nested LI's
.nav li li matches any LI's inside .nav that are inside another LI, i.e. nested LI's

In other words, LI elements inside LI elements, inside .nav are matched twice, but it shouldn't matter as jQuery removes duplicates, but it's uneccessary.

The real issue is that the event propagates, when you click a nested LI the event handler is called for the nested LI and the parent LI, so the click handler execute twice, and the class is first added, then removed (or vice versa) so there is no visible change.

Here's a simplified example


Just doing

$('#nav_button, .nav li')

should be enough, but you have to add event.stopPropagation() to make sure the event doesn't propagate to the next parent LI when a LI is called, here's an example


$('#nav_button, .nav li').on('click', function(e) {

     // do stuff