简体   繁体   中英

Fix responsive menu parent toggling - jQuery/Javasicript

I'm building a fully responsive accessible menu using jQuery/javascript and css.

I've got everything working fine, except for when the viewport is less than 535px and the toggle menu is displayed, a click on a parent doesn't expand the children, just links directly to that page.

I'd like it so that when you click a parent, say "Tools" for example, the children display and both the parent item and children are all clickable links.

Here's a staging site to look at: website link

Here's a sample of js:

            var ww = 0;

jQuery(document).ready(function($) {

    $(".menu").show();

    $(".menu .currenthas-child a, .menu .has-child a").each(function() {
        if ($(this).next().length > 0) {
            $(this).addClass("parent");
        };
    });

    $(".toggleMenu").click(function(e) {
        e.preventDefault();
        $(this).toggleClass("active");

        if($(this).hasClass("active")){
            //show menu
                $(".menu").removeClass("hidden").fadeIn(250);

        } else {
            //hide menu
                $(".menu").addClass("hidden");
        }

    });

    $(".menu li ul li").click(function(e) {
        if ($(".toggleMenu").hasClass("active")){
            $(".menu").toggleClass("hidden");
        }
    });

    //on click, anywhere on page, close all menu items
    $(document).click( function() {  
        $(".menu li").each(function() {
            if ($(this).hasClass("hover") || $(this).hasClass("keyhover")) {
                $(this).removeClass("hover");
                $(this).removeClass("keyhover");
                //console.log('hover removed');
            }
        });
    });


    //Focus State - Navigation
    $(".menu li").focusin(function (e) {
        if (!$(this).hasClass("keyhover")) {
            $(this).addClass("keyhover");
            showElement($(".menu"));
        } 
        //console.log('menu item focusin');
    });

    //Blur State - Navigation
    $(".menu li").focusout(function (e) {
        if ($(this).hasClass("keyhover")) {
            $(this).removeClass("keyhover");
        } 
        if ($(this).hasClass("hover")) {
            $(this).removeClass("hover");
        } 
        //console.log('menu item focusout');

    });

    //Focus State - Navigation Sub Items
    $(".menu li ul li").focusin(function () {
        if (!$(this).hasClass("glow")) {
            $(this).addClass("glow");
        } 
    });

    //Blur State - Navigation Sub Items
    $(".menu li ul li").focusout(function () {
        if ($(this).hasClass("glow")) {
            $(this).removeClass("glow");
        } 
    });

    //on window resize, recheck size and adjustMenu
    $(window).bind('resize orientationchange', function() {

        ww = viewportSize.getWidth();
        adjustMenu();

        //UN-COMMENT FOR DEBUG OUTPUT
        //var widthTest = document.documentElement.clientWidth;
        //var widthTest2 =  screen.width;
        //console.log("document.documentElement.clientWidth ="+widthTest);
        //console.log("screen.width = "+widthTest2);
        //console.log("viewport().width = "+ww);
        //var mql = window.matchMedia("screen and (max-width: 47.938em)");
        //console.log(mql);
    });

    var hideElement = function(elementToModify) {
        elementToModify.addClass("hidden");
    }

    var showElement = function(elementToModify) {
        elementToModify.removeClass("hidden");
    }

    var adjustMenu = function() {

        if (ww <= 535) {

            $(".toggleMenu").css("display", "inline-block");
            if (!$(".toggleMenu").hasClass("active")) {
                hideElement($(".menu"));
            } else {
                showElement($(".menu"));
            }

            $(".menu li h2.parent").unbind('click').bind('click', function(e) {
                // must be attached to anchor element to prevent bubbling
                e.preventDefault();

                if (e.stopPropagation){
                    e.stopPropagation();
                }
                else if(window.event){
                   window.event.cancelBubble=true;
                }

                //close any sibling menu items
                //$(this).parent().siblings('li').removeClass("hover");
                //$(this).parent().siblings('li').removeClass("keyhover");

                //handle click request
                if (!$(this).parent().hasClass("hover")) {
                    $(this).parent().addClass("hover");
                    //console.log('hover added');
                } else {
                    $(this).parent().removeClass("hover");
                    $(this).parent().removeClass("keyhover");
                    //console.log('hover removed');
                }

            });

        } 
        else if (ww > 535) {

            $(".toggleMenu").css("display", "none");
            $(".toggleMenu").removeClass("active");

            //show menu parents
            showElement($(".menu"));

            //hide any popped up menu sub-items
            $(".menu li").removeClass("hover");

            $(".menu li h2.parent").unbind('click').bind('click', function(e) {
                // must be attached to anchor element to prevent bubbling
                e.preventDefault();

                if (e.stopPropagation){
                    e.stopPropagation();
                }
                else if(window.event){
                   window.event.cancelBubble=true;
                }

                //close any sibling menu items
                $(this).parent().siblings('li').removeClass("hover");
                $(this).parent().siblings('li').removeClass("keyhover");

                //handle click request
                if (!$(this).parent().hasClass("hover")) {
                    $(this).parent().addClass("hover");
                    //console.log('hover added');
                } else {
                    $(this).parent().removeClass("hover");
                    $(this).parent().removeClass("keyhover");
                    //console.log('hover removed');
                }                
            });
        } 
    }

    //initialize the menu
    ww = viewportSize.getWidth();
    adjustMenu();
});

I think what you want is a strange behavior for your menu. How to close the sub-menu if the second click on the main link redirects to this page ?

That said, you can do what you want like this :

  $(".menu li").click(function(e) {
    if (!$(this).children('ul').is('.open')) {
      e.preventDefault();
      $(this).children('ul').addClass('open').css({'left' : '0px'});
    }
  });

It's better to test if the sub-menu is visible or not but you have to change the CSS of your .sub-menu class with display:none in place of left: -9999px

UPDATE

You can't have a slideDown effect on your sub-menus because they have a position : absolute attribute. So you need to deal with media queries to change that and set it just a display : none attribute in place. This way you can use a simple slideDown effect on click event and prevent the event if the corresponding sub-menu is not visible.

Take a look at this sample :

 $(document).ready(function(){ $(".dropdown").click(function(e) { if (!$(this).children('ul').is(':visible')) { e.preventDefault(); $(this).children('ul').slideDown(); } }); }); 
 *, *:before, *:after { margin: 0; padding: 0; box-sizing: border-box; } ul { list-style-type: none; width: 100%; } ul li { display: block; position: relative; } ul li a { color: #fff; text-decoration: none; cursor: pointer; padding: 10px 20px; display: block; width: 100%; } ul > li > a { background: #28AADC; } ul li a:hover { background: #00648C; } ul.submenu { display: none; } ul.submenu > li > a { background: #FFBE4F; } nav > ul { width: 400px; } @media screen and (min-width:536px){ nav > ul > li { width: 33.33%; float: left; } nav > ul > li:hover ul.submenu { display:block; } ul.submenu { position: absolute; } } @media screen and (max-width:535px){ nav > ul > li { width: 100%; float: none; } } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> <nav> <ul> <li class="dropdown"> <a href="http://stackoverflow.com">Nav 1</a> <ul class="submenu"> <li><a href="#">Nav 1.1</a></li> <li><a href="#">Nav 1.2</a></li> <li><a href="#">Nav 1.3</a></li> <li><a href="#">Nav 1.4</a></li> </ul> </li> <li class="dropdown"> <a href="http://stackoverflow.com">Nav 2</a> <ul class="submenu"> <li><a href="#">Nav 2.1</a></li> <li><a href="#">Nav 2.2</a></li> <li><a href="#">Nav 2.3</a></li> <li><a href="#">Nav 2.4</a></li> </ul> </li> <li class="dropdown"> <a href="http://stackoverflow.com">Nav 3</a> <ul class="submenu"> <li><a href="#">Nav 3.1</a></li> <li><a href="#">Nav 3.2</a></li> <li><a href="#">Nav 3.3</a></li> <li><a href="#">Nav 3.4</a></li> </ul> </li> </ul> </nav> 

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