Jquery : Dropdown menu not working correctly on mobile devices

Tags: , , ,



I’m currently working on making a website responsive and I’m working on the navigation menu.

I have a preheader which shows some social media icons and other stuff. Using a media query, I display a menu button on smaller screens and hide the full navigation menu. When the button is clicked, the nav div slides down and displays the menu items in block format. The problem I have is that when I try to use the menu button on a mobile device, the div will slide down but it disappears as soon as I do any sort of scrolling. I tested the site on an Iphone5s, an Ipad Air 2, a Samsung Galaxy Note 4 and the result is always the same: I click the menu button, the menu shows up, but disappears whenever I scroll. I’ve tried different solutions but the problem won’t go away.

CSS

/* styles the preheader at the top of the page */
    .preheader{
    background-color: #333;
    position: relative;
    top:0;
    width: 100%;
        max-width: 100%;
    min-height: 30px; 
    height: auto;
    border-bottom: 1px solid #1e1e1e;

    }

    .preheader a  {
    float: right;
    text-decoration: none;    
    margin-top:2px;
    margin-right: 2px;
    color: white;
    padding: 5px;
    font-size: 15px;
    }

    .preheader button {
    float: right;
    text-decoration: none;  
    padding: 5px;
    margin-right: 2px;
    color: white;
    border: none;
    background-color: Transparent;
    background-repeat:no-repeat;
    cursor:pointer;
    overflow: hidden;
    outline:none;
    }

    .preheader button:hover {
    opacity: 0.5;   
    }
    .preheader a.preheaderbutton  {
    color: white;
    font-family: "Constantia","Lucida Bright",Lucidabright,"Lucida Serif",Lucida,"DejaVu Serif","Bitstream Vera Serif","Liberation Serif",Georgia,serif;
    font-size: 10px;
    text-transform: uppercase;
    border: 2px solid deepskyblue;
    margin: 0;

    }
    .preheader a.preheaderbutton:hover {
    color: black;
    background-color: white;
    }

    .mobileMenuWrapper {
    width: 100%;
    height: auto;
    position: relative;
    display: none;
    background-color: #111;
    color: white;
    -moz-transition: 0.45s;
    -ms-transition: 0.45s;
    -webkit-transition: 0.45s;
    transition: 0.45s;
    }

    .searchDiv {
    width: 100%;
    height: 80px;
    display: none;
    background-color: #111;
    -moz-transition: 0.45s;
    -ms-transition: 0.45s;
    -webkit-transition:  0.45s;
    transition: 0.45s;
    }

    .searchForm {
    color: #fff;
    }

    .searchLabel {
    margin-left: 50px;
    color: #808080;
    text-transform: uppercase;  
    font-size: 1.1em;
    line-height: 1.5em;
    display: block;
    font-family: 'Gotham SSm A','Gotham SSm B';
    font-weight: 500;
    font-style: normal;
    padding: 0;
    z-index: 1;
    position: relative;
    }
    .searchDiv input[type="text"] {
    -webkit-appearance: none;
    -webkit-border-radius: 0;
    border-radius: 0;
    font-size: 1.4em;
    background-color: #111;
    border: none;
    height: auto;
    padding: 10px;
    margin-left: 40px;
    margin-top: -5px;  
    }

    .searchDiv input[type="submit"] {
    float: right;
    margin-top: -40px;
    display: flex;
    }
    /*Display the header at the top of the page*/
    header {
    margin: 0px;
    background: #bb0000;
    color: white;
    padding: 0px;
    height: auto;
    width: 100%;
    position: relative;
        max-width: 100%;
    border-top: 1px solid #ab0000;
    border-bottom: 1px solid #9a0000;


    }
    /*Controls the size of the text in the header*/
    header > h1 {
    text-align: center;
    margin-left: 0px;
    font-size: 40px;
    font-family: sans-serif;
    padding: 0px;
    margin-bottom: -0.4em;
    }


    header > p{
    padding: 0px;
    font-family: "Gabriola";
    font-size:25px;
    margin-top: 0px;

    }

nav {  
        margin: 0px;
        display: block;
/*         height: 200px;*/

    }

    /*Sets the nav bar in a horizontal manner. Hides the pointers for the list and ensures there's no scroll bar*/
    nav ul {
    display: flex; 
    flex-direction:row;
    margin: 0px;
    padding: 0px;
    list-style-type: none;
    border-top: 1px solid #9a0000;
    justify-content:center;
    }

    /*Styles each of the individual items in the nav bar list. Adds color and changes their font. Adds a border at the end*/
    nav ul li {
    flex: 1 0 auto;
    font-family: Constantia,"Lucida Bright",Lucidabright,"Lucida Serif",Lucida,"DejaVu Serif","Bitstream Vera Serif","Liberation Serif",Georgia,serif;
    display: inline-block;
    font-size: 1em;
    font-weight: bolder;
    padding: 0;
    }

    /*Determines how the links inside the navbar will be displayed.Gives them a background color*/
    nav ul li a {
    display: block;
    background: #bb0000;
    height: 25px;
    text-align:center;
    padding: 7px 8px;
    text-transform: uppercase;
    -moz-transition: 0.45s;
    -ms-transition: 0.45s;
    -webkit-transition:  0.45s;
    transition: 0.45s;
    }
    /*Shows how unvisited links will look*/
    nav ul li a:link{
    text-decoration: none;
    color: whitesmoke;
    }

    /*Changes the color inside visited links*/
    nav ul li a:visited {
    color: whitesmoke;
    height: 25px;
    }
    /*Determines what happens when you hover a link*/
    nav ul li a:hover{
    color: black;
    background-color: white;
    }

    .nolink:hover{
    cursor:default;

    }

    /*Shows what happens a link is active (page you are currently on)*/
    nav ul li a.active {
    background-color: indianred;
    color: white;
    }

    /*Styles what happens when you hover an active link on an active page*/
    nav ul li a.active:hover {
    background-color: #bb0000;
    color: white;
    }

    /*Dropdown stuff*/

    /* deals with level 1 submenus. Determines how they appear */
    .dropdown-content {
    display: none;
    position: absolute;
    color: black;
    min-width: 160px;
    border-bottom: 0.5px solid deepskyblue;
    box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
    z-index: 1;
    }

    /* Deals with level 2 submenus. Determines how and where they appear */
    .subsubmenu {
    display: none;
    position: absolute;
    left: 223px;
    top: 47%;
    color:black;
    min-width: 160px;
    box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
    z-index: 1;
    }
    ul li .dropdown-content a:link{
    text-decoration: none;
    color: whitesmoke;
    }

    ul li .subsubmenu a:link{
    text-decoration: none;
    color: black;
    }

    /*Changes the color inside visited links*/
    ul li .dropdown-content a:visited {
    color: whitesmoke;
    margin-left: 60px;
    height: 25px;
    }

    ul li .subsubmenu a:visited {
    color: black;
    margin-left: 60px;
    height: 25px;
    }

    /* Styles the links inside level 1 submenus */
    .dropdown-content a {
    padding: 8px 10px;
    text-decoration: none;
    display: block;
    text-align: left;
    font-size: 12px;
    background-color: black;
    }

    /* Styles the links inside level 2 submenus */
    .subsubmenu a{
    padding: 8px 10px;
    text-decoration: none;
    display: block;
    text-align: left;
    font-size: 12px;
    background-color: #f9f9f9;
    }
    .dropdown-content a:hover { 
    background-color: #bb0000;    
    }

    .subsubmenu a:hover {   
    background-color: #bb0000;
    }

    .subdropdown:hover .subsubmenu {
    display: block;
    color: whitesmoke;
    }

    /* Making the Menu Responsive i.e workable on screens of different sizes */
#mobileMenuButton {
    display: none;
}


    .nav-toggle-label {
        position: absolute;
        width: 1px;
        height: 1px;
        padding: 0;
        margin: -1px;
        overflow: hidden;
        clip: rect(0, 0, 0, 0);
        border: 0;
    }
    /*Hides the menu icon when the page is greater than 600pixels*/
    .icon {
        display: none;
    }
    @media screen and (max-width: 768px){

         #mobileMenuButton {
    /*    width: 30px;*/
/*        float:right;*/
            padding-top: 8px;
            cursor: pointer;
            background: transparent;
            outline: none;
            border: none;  
            display: block;
            margin: auto;
            color: white;
         }
         header h1 {
            font-size: 35px;
        }
        header p {
            font-size: 20px;
            margin-bottom: 3px;
            margin-top: 3px;
        }
        .icon{
        display: block;  
            margin-top: 10px;
        }
        .hideOnMobile {
        display: none;
        }
        .preheader {
        position: fixed;
        top: 0;
        left: 0;
        width: 100%;
/*        max-width: 100%;*/
        height: 30px;
        z-index: 1;     
        }   


        #returnToTop {
/*        position: absolute;*/
        }

        header {
        margin-top: 30px;
        }

        .mainContent {
            }

         nav ul {
            display: block; 
            }

        nav ul li {
            display: block;
/*            border-bottom: 1px solid navy;*/
        }

        nav ul li:first-child {
/*            border-top: 1px solid black;*/
        }

        nav ul li:last-child {
            border-bottom: none;
        }

        #menu  {
            display: none;
        }

            /* deals with level 1 submenus. Determines how they appear */
        .dropdown-content {
            display: none;
            position: relative;
        }
        /* Deals with level 2 submenus. Determines how and where they appear */
        .subsubmenu {
            display: none;
            position: relative;
            width: 100%;
            left: 0;
            top:0;
        }

         .dropdown-content a {
            text-align: center;    
        }   
            /* Styles the links inside level 2 submenus */
        .subsubmenu a{
            text-align: center;
        }
    }

JS

$(document).ready(function() {

    if (window.innerWidth > 768){
        $( '.dropdown' ).hover(
        function(){
            $(this).children('.dropdown-content')
                .delay(100)
                    .slideDown(400);

        },
        function(){
            $(this).children('.dropdown-content')
                .clearQueue()
                .slideUp(0);
        }
       ); 
    }

     $(window).resize(function () {
         if ($(window).width() > 768) {
             $( '.dropdown' ).hover(
            function(){
                $(this).children('.dropdown-content')
                    .delay(100)
                        .slideDown(400);

            },
            function(){
                $(this).children('.dropdown-content')
                    .clearQueue()
                        .slideUp(100);
            }
           ); 
         } 
     }).resize();  

});

// drop down functionality for mobile
$(document).ready(function(){


//    $('#myTopnav').prepend('');


    $(window).on('resize', function(e){
       if ($(window).width() > 768){
           $('#menu').show();
           $('#menu').css({
            display : 'flex'
        });
       } else if ( window.innerWidth < 768){
           $('#menu').hide();
           $('#menu').css({
            display : 'none'
        });
       }
    });


    $('#mobileMenuButton').click(
      function(e) {
           $('#menu').toggle(700);
              $('#menu').css({
                display : 'block'
            });
//          e.stopPropagation();
          $('#schoolHeader').focus();
            }
        );
}); 

Answer

As indicated in the comments, the issue lies in this block of code;

$(window).on('resize', function(e){
   if ($(window).width() > 768){
       $('#menu').show();
       $('#menu').css({
        display : 'flex'
    });
   } else if ( window.innerWidth < 768){
       $('#menu').hide();
       $('#menu').css({
        display : 'none'
    });
   }
});

… you’ve only noticed this on mobile browsers, because most mobile browsers begin to hide the address bar as you scroll, which causes a resize event on the window, and, given your above event handler, would result in the #menu being hidden.

You could however, also replicate the issue by shrinking the size of your browser to be < 768px, opening the menu, then resizing the browser some more.


To fix, I would change your handler, so that it will only change the elements if the width goes across your 768px boundary;

var wasSmall;

$(window).on('resize', function(e) {
   var isSmall = $(window).width() < 768;

   // If nothing has changed, don't do anything...
   if (isSmall === wasSmall) {
       return;
   }

   if (isSmall) {
       $('#menu').hide();
       $('#menu').css({
          display : 'none'
       });
   } else {
       $('#menu').show();
       $('#menu').css({
        display : 'flex'
       });
   }

   wasSmall = isSmall;
});


Source: stackoverflow