简体   繁体   中英

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') only #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?

jquery:

var mobileMenu = function () {

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

        if (currentPosition == 'closed') {
            $('.nav').addClass('open');
            currentPosition = 'open';
        }
        else {
            $('.nav').removeClass('open');
            currentPosition = 'closed';
        }
    });
};

html:

<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>
                    </ul>
                </li>
                <li><a href="#">About Us</a></li>
                <li><a href="#">Contact</a></li>
            </ul>
        </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, ie 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

FIDDLE

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

FIDDLE

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

     // do stuff
});

As @adeneo said in nested li function will call twice unnecessarily. I think the other way to achieve this is divide click grabber in two selectors like below:

$('.nav').click(function() {

    if (currentPosition == 'closed') {
        alert('open');
        $('.nav').addClass('open');
        currentPosition = 'open';
    }
    else {
        alert('close');
        $(this).removeClass('open');
        currentPosition = 'closed';
    }
});

$('.nav > li > li').click(function() {

    if (currentPosition == 'closed') {
        alert('open');
        $(this).addClass('open');
        currentPosition = 'open';
    }
    else {
        alert('close');
        $('.nav').removeClass('open');
        currentPosition = 'closed';
    }
});

I wrote a fiddle to do what you expect. Please check and comment if that helpful.

http://jsfiddle.net/QMaster/y7d6osoq/

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM