Deactivating one div's class upon clicking on another div

Below is the HTML code snippet:

 <div class="container">
  <ul class="navbar">
    <li class="nb-link"><a>Home</a></li>

    <li class="dropdown">
      <a>CBSE</a>
      <ul class="dropdown-menu">
        <li>10th Standard</li>
        <li>12th Standard</li>
      </ul>
    </li>

    <li class="dropdown">
      <a>Engineering</a>
      <ul class="dropdown-menu">
        <li>JEE - Main</li>
        <li>JEE - Advanced</li>
      </ul>
    </li>
  </ul>

There are two dropdowns included. Clicking on one reveals its content, but clicking on another one while the first remains open causes an overlapping issue. The current JavaScript function to handle this behavior is as follows:

 $(document).ready(function() {
    $('.dropdown').click(function() {
        var $this = $(this);

      if ($this.children('.dropdown-menu').hasClass('open')) {
        $this.removeClass('active');
        $('.navbar').$this.children('.dropdown-menu').removeClass('open');
        $this.children('.dropdown-menu').fadeOut("fast");
      } 

        else {
          $this.addClass('active');
          $this.children('.dropdown-menu').addClass('open');
          $this.children('.dropdown-menu').fadeIn("fast");
        }

    });

});

How can I enhance the JavaScript functionality so that clicking on a new dropdown closes the previous one? Additionally, how can I ensure that clicking anywhere on the page will close all open dropdowns?

Answer №1

Here is a solution you can try out:

$(document).ready(function() {
    $('.dropdown').click(function() {
        var $this = $(this);
        $('.dropdown').not($this).removeClass('active')
        $('.dropdown-menu').not($this.find('.dropdown-menu')).removeClass('open');
        $this.toggleClass('active');
        $this.find('.dropdown-menu').toggleClass('open');
    });
});

View Demo

This function comes in handy when selectors are not the target.

// Function for handling cases where selectors are not the target
function actionwindowclick(e , selector , action){
            if (!$(selector).is(e.target) 
                && $(selector).has(e.target).length === 0) 
            {
            action();
        }
}

You can implement it in a window click event like this:

$(window).on('click', function(e){
     actionwindowclick(e , ".dropdown , .dropdown-menu" , function(){
         $('.dropdown').removeClass('active')
         $('.dropdown-menu').removeClass('open');
     });
});

View Demo

Note: You may need to use event.stopPropagation() when clicking on the .dropdown-menu element itself

$('.dropdown-menu').click(function(e) {
   e.stopPropagation()
});

Answer №2

Here's a suggestion to improve your code:

$(document).ready(function() {<br>
        $('.dropdown').click(function() {<br>
            var $this = $(this);<br>
            $this.children('.dropdown-menu').toggleClass('open');<br>
            if ($this.children('.dropdown-menu').hasClass('open')) {<br>
                $this.removeClass('active');<br>
                $this.children('.dropdown-menu').fadeOut("fast");<br>
            }<br>
            else {<br>
                $this.addClass('active');<br>
                $this.children('.dropdown-menu').fadeIn("fast");<br>
            }<br>
        });<br>
    });

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

The hyperlink element is failing to load in a particular frame

I've been attempting to load the URL of an anchor tag in a specific frame. I've tried various methods through online searches, but have not found a satisfactory solution. Can someone please assist me with how to load the href URL in a particular ...

The jQuery has not been activated

I currently have a list of flags displayed in HTML along with some jQuery code to manage user actions. HTML <a href="#" class="chosenflag" data-flag="de"><img class="flag" src="" alt="" /></a> <ul class="choices"> <li&g ...

Use jQuery to swap out every nth class name in the code

I am looking to update the 6th occurrence of a specific div class. This is my current code <div class="disp">...</div> <div class="disp">...</div> <div class="disp">...</div> <div class="disp">...</div> < ...

In Vue, emitting does not trigger the parent component to update its properties

The emit is functioning properly, as I can observe in the vue developer tool. However, the property in the parent element is not updating. Child Component: <template> <div> <ul> <li v-for="(option, index) in opt ...

What is the best way for Cucumber to move on to the next annotation only after ensuring all async requests from the previous one have finished processing?

I am looking to set up a basic test using Selenium and Cucumber for logging into my web application and confirming that the main page is displayed correctly. Currently, all three tests are returning true even before the page is fully loaded. The issue ar ...

What is the reason behind the removal of the "disabled" attribute when setting the "disabled" property to false?

Initially, I have a disabled button: <button disabled="disabled">Lorem ipsum</button> When using button.getAttribute('disabled'), it returns "disabled". But once the button is enabled with JavaScript: button.disabled = false; The ...

Is tsconfig.json Utilized by Gatsby When Using Typescript?

Many blog posts and the example on Gatsby JS's website demonstrate the use of a tsconfig.json file alongside the gatsby-plugin-typescript for TypeScript support in Gatsby. However, it seems like the tsconfig.json file is not actually utilized for conf ...

Paginator for Angular Material Cards

This section contains the TypeScript file for a component import { MatTableDataSource, MatPaginator } from "@angular/material"; import { FoodService } from "./food.service"; import { Food } from "./food"; @Component({ selec ...

Eliminate gaps created by grid rows by incorporating elements of varying heights

This is the standard format of the page: * { margin: 0; padding: 0; } img { width: 100%; float: left; } #grid { display: grid; grid-template-columns: repeat(3, 1fr); } #test-one { grid-column-start: 1; grid-column-end: 2; width: 100 ...

In what situations should the `#` symbol be used to select a DOM element?

There are times when I have to retrieve elements in the following ways: var object = document.getElementById('ObjectName'); Other times, it's done like this: var object = document.getElementById('#ObjectName'); What distinguishes ...

Incorporate create-react-app with Express

Issue - I am encountering a problem where I do not receive any response from Postman when trying to access localhost:9000. Instead of getting the expected user JSON data back, I am seeing the following output: <body> <noscript>You need to ...

How to send a complex object containing a Dictionary to an MVC controller action using JQuery

Question: I have a model with a Dictionary type field that needs to be posted to the backend controller action. How should I define the model object in JQuery? I keep encountering a primitive error from the ajax call with the code below: var templateBuil ...

Transmitting content via ajax to a dropdown list does not always ensure that the selection is fully set

Using AJAX, I am sending an ID to retrieve a specific name (label) along with its code. This retrieved data will be displayed as the selected value in my dropdown list within a Bootstrap Modal Form. Currently, I am able to fetch the code enclosed within t ...

Guide on resolving a "res is not defined" issue in Node.js

I've been struggling to test the controller logic for a user validation module, but I keep encountering an error that says "res is not defined" even after trying to define it. How can I properly define it so that it runs through the condition statemen ...

The Angular framework's structure is loaded in a combination of synchronous and asynchronous ways once the primeng tableModule

Encountered this error while trying to load the TableModule from primeng into my components module file and running 'npm run packagr': Maximum call stack size exceeded To address this, I switched my primeng version from primeng12 to primeng11.4. ...

Avoid altering the Summernote HTML WYSIWYG editor page due to content CSS

We are currently utilizing the Summernote wysiwyg editor to review and preview html content, some of which contains external stylesheet references. This css not only affects Summernote itself but also alters the styling of the parent page where Summernote ...

Determine if an object has been submitted in a MEAN / AngularJS application

I am working with an AngularJS frontend and using Express, Node, and MongoDB on the backend. My current setup is as follows: // my data to push to the server $scope.things = [{title:"title", other properties}, {title:"title", other properties}, {titl ...

What is the technique for accessing dynamic object properties in Javascript?

I am dealing with a dynamic object where the property values change based on different data sets. For example: MyObj = { country:"Ind", Place:"Pune"} Now, I have a data value that determines which property value I need to retrieve. var MyArr = this.Filt ...

Having trouble combining different styles with Material-ui and Radium?

Trying to integrate Radium with Material-ui has presented a challenge. Attempting to apply multiple styles to a single Material-ui component results in no styling being applied. For instance, the following code fails to render any styling: <MenuItem st ...

Ways to create a separator or divider between rows in a table

I'm currently working on creating a table layout and I want to include dividers similar to those seen on this website. Specifically, I am looking to have thin grey dividers between rows. I've attempted the following code, but it doesn't seem ...