Avoid activating jQuery functions based on certain screen widths for menu/navigation system

Recently, I've delved into the world of jQuery and attempted to create a simple menu system. The menu is designed to expand its submenu when hovering over the list item at screen widths larger than 480px, and to expand when clicking on the list item at widths less than 480px.

I thought I could utilize Modernizr's media query detection feature to enhance my code. However, my attempts have not been successful as seen in my demo here. Try hovering over the 'Properties' li tag to see the issue.

The problem seems to lie in the code's failure to recognize screen resizing properly. It functions correctly at >480px and <480px if you refresh the browser at those specific widths. But when you resize the browser, the functions still trigger incorrectly!!

Here's my code:

// Main nav dropdown animation

$(document).ready(function() {
  function doneResizing() {
    if(Modernizr.mq('screen and (min-width: 481px)')) {

        $("#sub-menu").hide();

        $("#show-investment-type-nav").hover(function() {
            $(this).find("#sub-menu").stop(true, true).slideDown("fast");
        }, function() {
            $(this).find("#sub-menu").stop(true, true).fadeOut("fast");
        });

    }
    else if(Modernizr.mq('screen and (max-width: 480px)')) {

      $("#sub-menu").hide();

      var next_move = "show";

        $("#show-investment-type-nav").click(function() {

            $('#sub-menu').slideToggle(100);

            if (next_move === "show") {
                $("body").addClass("nav-active");
                $("#site-nav #icon").empty().html("&#59236;");
                $("#site-nav #nav-margin-down").animate({"margin-top": "163"}, 100);
                next_move = "hide";
            } else {
                $("body").removeClass("nav-active");
                $("#site-nav #icon").empty().html("&#59238;");
                $("#site-nav #nav-margin-down").animate({"margin-top": "0"}, 100);
                next_move = "show";
            }
        });
    }
  }

  var id;
  $(window).resize(function() {
    clearTimeout(id);
    id = setTimeout(doneResizing, 0);
  });

  doneResizing();
});

If anyone can shed some light on why this glitch is happening, I'd greatly appreciate it! I'm eager to learn from my mistakes!

Thanks for your help!

Answer №1

Here is a revised version of the code that separates the click handler from the resize handler for better event handling. Moving next_move to the global scope may help and using data() to add values to menu elements could be a more efficient option:

var next_move = "show";

$(document).ready(function () {

    $("#show-investment-type-nav").click(function () {
        if (Modernizr.mq('screen and (max-width: 480px)')) {
            $('#sub-menu').slideToggle(100);
            if (next_move === "show") {
                $("body").addClass("nav-active");
                $("#site-nav #icon").empty().html("&#59236;");
                $("#site-nav #nav-margin-down").animate({
                    "margin-top": "163"
                }, 100);
                next_move = "hide";
            } else {
                $("body").removeClass("nav-active");
                $("#site-nav #icon").empty().html("&#59238;");
                $("#site-nav #nav-margin-down").animate({
                    "margin-top": "0"
                }, 100);
                next_move = "show";
            }
        }
    });

    function doneResizing() {
        if (Modernizr.mq('screen and (min-width: 481px)')) {
            $("#sub-menu").hide();
            $("#show-investment-type-nav").hover(function () {
                $(this).find("#sub-menu").stop(true, true).slideDown("fast");
            }, function () {
                $(this).find("#sub-menu").stop(true, true).fadeOut("fast");
            });
        } else if (Modernizr.mq('screen and (max-width: 480px)')) {
            $("#sub-menu").hide();  
            next_move = "show";
        }
    }

    var id;
    $(window).resize(function () {
        clearTimeout(id);
        id = setTimeout(doneResizing, 0);
    });

    doneResizing();
});

Answer №2

The issue appears to have been resolved with this solution, although it may be considered more of a temporary fix than a permanent one!

var move_next = "display";

$(document).ready(function () {

  // Implementation of touch device workaround to prevent submenu from being displayed during initial load
  $('#sub-menu').css("display","block");

    $("#show-investment-type-nav").click(function() {

      if (Modernizr.mq('screen and (max-width: 480px)')) {
        $('#sub-menu').slideToggle(100);
        if (move_next === "display") {
          $("body").addClass("nav-active");
          $("#site-nav #icon").empty().html("&#59236;");
          $("#site-nav #nav-margin-down").animate({"margin-top": "163"}, 100);
          move_next = "hide";
        } else {
          $("body").removeClass("nav-active");
          $("#site-nav #icon").empty().html("&#59238;");
          $("#site-nav #nav-margin-down").animate({"margin-top": "0"}, 100);
          move_next = "display";
        }
      }
    });

  function resizingCompleted() {
    if (Modernizr.mq('screen and (min-width: 481px)')) {

      // Hide the submenu
      $("#sub-menu").hide();

      // Reset margin for li tags in case the screen was expanded while the nav was open
      $("#site-nav #nav-margin-down").css("margin-top","0");

      $("#show-investment-type-nav").hover(function() {
          $(this).find("#sub-menu").stop(true, true).slideDown("fast");
      }, function () {
          $(this).find("#sub-menu").stop(true, true).fadeOut("fast");
      });
    } else if (Modernizr.mq('screen and (max-width: 480px)')) {

      // Resolves the touch device issue when tapping away from an expanded submenu... took quite a bit of trial and error!
      $('#sub-menu').slideUp(100);
      $("#site-nav #nav-margin-down").animate({"margin-top": "0"}, 100);

      // To ensure that if the nav is expanded and move_next = "hide", the hover event doesn't hide() the submenu
      if (!Modernizr.touch) {
        $("#show-investment-type-nav").hover(function() {
          $("#sub-menu").hide();
          if (move_next === "hide") {
            $("#sub-menu").show();
          }
        });
      }

      move_next = "display";
    }
  }

  var identifier;
  $(window).resize(function () {
    clearTimeout(identifier);
    identifier = setTimeout(resizingCompleted, 0);
  });

  resizingCompleted();
});

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Exploring the magic of Hover effects using CSS and JQuery

I am exploring ways to enhance the display of an element when hovering over it. I have implemented a button and my objective is for the first click to activate the hover effect, while the second click will reset it. However, I am facing an issue where the ...

What is the reason behind one function triggering a re-render of a component while the other does not in Next.js?

I am currently working on a Next.js web application where one of the pages contains two functions that utilize useState() to add or remove emails from an array. const [invites, setInvites] = useState([]) // other code const lmao = () => { console.lo ...

Make sure to close any existing Featherlight windows before trying to open another one

I'm setting up multiple featherlight instances when the page loads jQuery('.feedback').featherlight(jQuery( "#feedback-box" ), { closeIcon: 'close'}); jQuery('#imprint').featherlight(jQuery( "#imprint-box" ), { closeIcon ...

I'm encountering an issue with my React master component not being able to locate the

I am having trouble importing a component in my APP.js file. I have been attempting to bring MainComponent into the app.js component, but I am facing difficulties in fetching the component. Any assistance in resolving this issue would be greatly apprecia ...

Tips for splitting the json_encode output in Javascript

Looking for help with extracting specific values from JSON data retrieved via PHP and AJAX. I only want to display the agent name in my ID, not the entire object that includes "name" : "Testing". Here is the console output: [{"agent_module_id":"1","agen ...

Encountering a 404 error when attempting to access static files within a directory using Express Js

Organizing my static files has been a breeze with multiple directories. I have some static files in the client directory, while dashboard-related files are nested within the src directory. Here is how my directory structure looks: / | client //housing sta ...

Serving static files in Next.js with specific extensions without triggering a download

I'm facing an issue where I need to serve the stellar.toml file in domain/.well-known/stellar.toml with the content type as text/plain. The current configuration works only when the stellar file is saved without an extension. It is essential for me t ...

Ways to break down a collection of multiple arrays

Looking to transform an array that consists of multiple arrays into a format suitable for an external API. For example: [ [44.5,43.2,45.1] , [42, 41.2, 48.1] ] transforming into [ [44.5,42], [43.2,41.2] , [45.1, 48.1] ] My current code attempts this ...

Using HTML and C# to Deliver Emails

I've encountered a challenge with my HTML page that includes a textbox for users to input their email. When the submit button is clicked, an email should be sent to a specific email address defined in the code, and a pop-up box indicating "Email Sent" ...

Safari having trouble auto-playing Vimeo iframe embed

Update 6/26/23: Seems like a mysterious change occurred, as now the Vimeo video on project pages is playing automatically for me in Safari without any specific reason. It's working fine on Chrome too. Not sure if Vimeo made an update or if it's r ...

What is the best way to create underlined text that is either left-aligned or centered?

I am looking to replicate this specific style of decoration in a full width container. My goal is to have it aligned to the left of the text and restricted to a maximum width. https://i.stack.imgur.com/H8DXT.png ...

Displaying all checkboxes within an array of forms

Hello, I have created a form with the following structure: <div class="row calc"> <div class="large 12 columns"> <div class="large-1 columns"> <label>Quantity</label> <input name="units[]" type="tex ...

"Trouble arises when dealing with nested object arrays in Formik and handling changes in a child

I am struggling with passing a value to handleChange in formik validation. To address this issue, I created a component whose quantity is dynamically added based on the number of numChild. My goal is to allow users to click an icon and add any number of sk ...

Eliminate all hover functionalities from the Kendo Menu component in ASP.NET MVC

Currently, I am working on a project and utilizing the Kendo Menu. However, the package includes hover styling that I do not want to use. Is there a way to disable or remove this styling? ...

Tips for eliminating the backslash introduced by JQuery

Switching back from framework 4.5 to 4.0 caused several issues that needed fixing. One significant change I noticed was that jQuery started escaping double quotes. Is there a way to stop this behavior? I attempted datatest = datatest.replace("\\ ...

Step by step guide on enabling link routing on a Material UI list item, excluding only one specific button within the list item

I am facing an issue with a component containing ListItem components from material ui. Each ListItem has a button, and the entire listitem should be clickable to route the app somewhere. However, when clicking the delete button, it also routes the app to ...

Utilizing Stripe for Payment Processing

I'm encountering a problem with getting Stripe charging to function properly. Despite having manually loaded Composer since it wouldn't install, I am not receiving any PHP errors and the token creation is running smoothly. There don't seem t ...

How can the edit feature be implemented in AngularJS?

I am struggling with implementing an edit field in AngularJS. Can someone please help me with this? Here is the code for my CRUD operations: var app = angular.module('myApp', []) app.controller('myCtrl', ['$scope', functio ...

How can I eliminate the border from the last child in a row within a responsive framework?

Put simply, I am trying to target not only the last child in a parent div, but also the last item in a row that adjusts based on screen size. I have a row of 4 elements (divs) with borders on all but the last one using :last-child. However, when the screen ...

Lack of intellisense support for .ts files in Visual Studio Code

Currently, I am using Visual Studio Code 1.17.2 on Arch Linux to kickstart my work with Node.js/Angular4. To avoid confusion caused by loosely typed code, I have decided to switch to TypeScript for my NodeJS server as well. This is why my main file is name ...