The functionality to Toggle submenus within a navigation menu using jQuery is not performing as anticipated

I implemented a horizontal menu using CSS, HTML, and jQuery. Clicking on a menu item displays a sub-menu.

The issue I'm facing is that when one submenu is open and I click on another menu item, the new submenu opens but doesn't hide the previous one.

UPDATE: I have refined the question to focus on this specific problem only.

$(".menus_li").click(function(e) {
  $(".blocks_ul", this).toggleClass('submenu-is-active');
});
a {
  color: #fff;
  text-decoration: none;
}

li {
  list-style: none;
}

.top-menu {
  z-index: 2;
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  display: flex;
  width: 100%;
  background: #0088ff;
  padding: 1rem;
  margin: 0;
}

.menus_li {
  font-weight: bold;
  margin-left: 1rem;
}

.blocks_ul {
  display: none;
  position: absolute;
  background: #fff;
  top: 100%;
  min-width: 120px;
  border-radius: 8px;
  padding: 1rem;
}

.blocks_ul a {
  color: #000;
}

.blocks_ul li {
  padding-left: 10px;
  font-weight: normal;
  padding: 0.4rem 0.7rem;
}

.blocks_ul.submenu-is-active {
  display: block;
}

.bg_submenu {
  background-color: rgba(0, 0, 0, 0.6);
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  z-index: 1;
  display: none;
}

.bg_submenu.show {
  display: block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div class="bg_submenu"></div>
<ul class="top-menu">
  <li class="menus_li"><a href="#">Cars +</a>
    <ul class="blocks_ul">
      <li><a class="menu-link" href="#">Mercedes</a></li>
      <li><a class="menu-link" href="#">Jeep</a></li>
      <li><a class="menu-link" href="#">Ford</a></li>
      <li><a class="menu-link" href="#">BMW</a></li>
      <li><a class="menu-link" href="#">Tesla</a></li>
    </ul>
  </li>
  <li class="menus_li"><a href="#">Computers +</a>
    <ul class="blocks_ul">
      <li><a class="menu-link" href="#">Apple</a></li>
      <li><a class="menu-link" href="#">Lenovo</a></li>
      <li><a class="menu-link" href="#">HP</a></li>
      <li><a class="menu-link" href="#">Dell</a></li>
      <li><a class="menu-link" href="#">Acer</a></li>
    </ul>
  </li>
</ul>

Answer №1

To modify your code according to the comments:

const $blocks = $(".blocks_ul");       // select all blocks
const $background = $(".bg_submenu");  // select background

$(".menus_li").on('click', e => {
  const $thisBlock = $(".blocks_ul", e.currentTarget);      // get current block

  $blocks.not($thisBlock).removeClass('submenu-is-active'); // remove class from other blocks
  $thisBlock.toggleClass('submenu-is-active');              // toggle the class on the current block
  $background.toggleClass('show', $thisBlock.hasClass('submenu-is-active')); // show the background only if the block is displayed
});

$('body').on('click', e => {
  const $clicked = $(e.target);  // identify the clicked target
  
  // check if the click originated in the menu
  if (!$clicked.hasClass('menus_li') && !$clicked.closest('.menus_li').length) {
    // if not, perform the following steps
    $blocks.removeClass('submenu-is-active'); // hide the menu
    $background.removeClass('show'); // hide the background
  }
})
a {
  color: #fff;
  text-decoration: none;
}

li {
  list-style: none;
}

.top-menu {
  z-index: 2;
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  display: flex;
  width: 100%;
  background: #0088ff;
  padding: 1rem;
  margin: 0;
}

.menus_li {
  font-weight: bold;
  margin-left: 1rem;
}

.blocks_ul {
  display: none;
  position: absolute;
  background: #fff;
  top: 100%;
  min-width: 120px;
  border-radius: 8px;
  padding: 1rem;
}

.blocks_ul a {
  color: #000;
}

.blocks_ul li {
  padding-left: 10px;
  font-weight: normal;
  padding: 0.4rem 0.7rem;
}

.blocks_ul.submenu-is-active {
  display: block;
}

.bg_submenu {
  background-color: rgba(0, 0, 0, 0.6);
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  z-index: 1;
  display: none;
}

.bg_submenu.show {
  display: block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div class="bg_submenu"></div>
<ul class="top-menu">
  <li class="menus_li"><a href="#">Cars +</a>
    <ul class="blocks_ul">
      <li><a class="menu-link" href="#">Mercedes</a></li>
      <li><a class="menu-link" href="#">Jeep</a></li>
      <li><a class="menu-link" href="#">Ford</a></li>
      <li><a class="menu-link" href="#">BMW</a></li>
      <li><a class="menu-link" href="#">Tesla</a></li>
    </ul>
  </li>
  <li class="menus_li"><a href="#">Computers +</a>
    <ul class="blocks_ul">
      <li><a class="menu-link" href="#">Apple</a></li>
      <li><a class="menu-link" href="#">Lenovo</a></li>
      <li><a class="menu-link" href="#">HP</a></li>
      <li><a class="menu-link" href="#">Dell</a></li>
      <li><a class="menu-link" href="#">Acer</a></li>
    </ul>
  </li>
</ul>

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

Trouble locating the ID selector within a nested Backbone view

Within this code snippet, I am utilizing the element controller pattern to display a collection of products. The main view template is rendering properly, showing all elements and the div selector "#cart-wrapper". However, when the main view calls the nest ...

Capturing jQuery ajax requests in Angular

Within my Angular application, I am utilizing the integrated $.couch API from CouchDB. My goal is to intercept every ajax request, regardless of whether it originates from Angular's $http service or jQuery's $.ajax (which is utilized by $.couch). ...

Tips for rotating a responsive table on a mobile device's screen

I am currently managing a blogger website that features an HTML table on the homepage. I am struggling with making this table responsive for mobile devices, and I would like it to look similar to the image provided below. Can someone guide me on how to ach ...

Achieving full coverage of cell content within a cell area by utilizing align-items in CSS Grid

Is it possible to achieve two conflicting goals using CSS Grid? In my design, I want the content in each cell to be vertically centered using align-items: center; At the same time, I need the entire area of the cell to be filled with color. However, ...

"Implementing interactive arrow buttons in a horizontal navigation bar using HTML, CSS, and JavaScript

Seeking advice on creating a horizontal navigation bar with arrow buttons at the sides, such as the one shown below. Despite extensive research, I have not found the exact solution I am looking for. This will be implemented in my Vue.js project. |<| P ...

Unable to modify the CSS properties of the titlebar in jQuery UI dialog

Is there a way to modify the background color of a jQuery UI dialog titlebar? Here is the code I am using: jQuery("#divId").dialog({ title: 'Information' }); jQuery("#divId .ui-dialog-titlebar").css("background-color", "red"); For m ...

Custom Angular directive for collapsing sub menus with CSS

I found a helpful article on creating collapsible menus and submenus using only Bootstrap and custom code for Angular 2, 4, 5, 6. I've been able to implement the logic successfully, but I'm facing an issue with multiple menus where clicking on an ...

Bootstrap select box gracefully fits within a dynamically adjusting height div

Can someone help me troubleshoot the issue with displaying/overflowing the .drop-down outside of the .item box in this demo? I need to keep the height of the .item as auto but for some reason, I can't enable overflow visible on it. .item{ backg ...

The 600 pixel wide page is not completely filling the 640 pixel width screen on a mobile device

Currently, I am conducting a test on a webpage using an iPhone 5s with a screen resolution of 1136 x 640 pixels. The meta tag is set as follows: <meta name="viewport" content="user-scalable=yes, initial-scale=1, width=device-width, shrink-to-fit=no"&g ...

javascript mobile nav event

My website utilizes a bootstrap feature for mobile devices where a left sidebar pops up when clicking a button. I am not very familiar with bootstrap, but I would like to link a javascript event to determine if the left sidebar is visible. How can I achiev ...

Display text when hovered over or clicked to insert into an HTML table

I have an HTML table connected with a component field gameArray and I need it to: Show 'H' when the user's cursor hovers over TD (:hover) and the corresponding field in gameArray is an empty string, Fill the gameArray field after a click. ...

To properly document the results, I must utilize a button to record the identification of a specific color

I'm working on a code that creates a clickable box which changes colors from black to green to white by going through different shades of green whenever the mouse is clicked. What I now need to do is implement a feature that displays the current shade ...

Utilizing nested flex containers with overflow-x property

I'm looking to set up a layout with 2 columns side by side. The first column should have a fixed width of 200px, while the second column should take up the remaining space on the screen. Additionally, I want the content in the second column to auto-sc ...

The function .innerHTML is not functioning correctly, at least in my opinion

When I utilize .innerHTML to insert text into a textarea, the script stops functioning if I manually begin editing the text in the textarea. Here is the code snippet: (function($){ addPort = function(name) { switch(name) { case 'name1': ...

jQuery's AJAX functionality may not always register a successful response

Below is the code snippet I am currently working with: $(".likeBack").on("click", function(){ var user = $(this).attr("user"); var theLikeBack = $(this).closest(".name-area").find(".theLikeBack"); $.a ...

Change the background color according to the user's input text

I want to create a text box where users can input color keywords like blue, lime, or black. When they click submit, I want the background color of the page to change accordingly. This is what I have so far: <label for="color">Color: </label> ...

Issues with Async Ajax functionality are being reported specifically in Safari browsers when a redirect

Encountering issues with an async Ajax call not functioning in Safari while working perfectly fine in other browsers. The problem arises when there is a redirect/link on the button or anchor that triggers the Ajax function. Here's a basic example: & ...

Tips on improving a function that verifies the existence of an image used as a CSS background to output a boolean value

I have encountered a challenge while working on a react file-upload component. The issue at hand is relatively simple - I aim to display an icon corresponding to the file extension for each uploaded file. These icons are loaded through css as background im ...

The presence of inline display causes gaps of white space

Located at the bottom of this webpage is a media gallery. The initial three images comprise the photo gallery, followed by video thumbnails inlined afterwards. However, there seems to be an issue with the alignment of each element within the video gallery. ...

Tips for concealing elements beyond div boundaries

First and foremost, I want to mention that my focus is on studying frontend development, so I could really use some assistance with a task. I am looking to create a tab slider where the content on the left and right will flank it, ensuring the tab slider ...