Struggling with your Dropdown Menu onclick functionality in Javascript? Let me lend

I am seeking assistance with implementing a Javascript onclick Dropdown Menu. The current issue I am facing is that when one menu is opened and another menu is clicked, the previous menu remains open. My desired solution is to have the previously open menu close automatically when a new menu is opened.

<!DOCTYPE HTML>
<html>

<head>
  <style>
    * {
      box-sizing: border-box;
    }
    
    body {
      margin: 0;
    }
    
    .navbar {
      width: 100%;
      padding: 0 10% 0 10%;
      overflow: hidden;
      box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.16), 0 2px 10px 0 rgba(0, 0, 0, 0.12);
    }
    
    .dropbtn {
      font-size: 16px;
      border: none;
      outline: none;
      padding: 21.5px 20px;
      background-color: inherit;
      margin: 0;
      cursor: pointer;
      font-weight: bolder;
      color: #2d3436;
    }
    
    .dropdown {
      float: left;
    }
    
    .dropdown-content {
      display: none;
      position: absolute;
      background-color: #fff;
      min-width: 460px;
      box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.16), 0 2px 10px 0 rgba(0, 0, 0, 0.12);
      height: 450px;
    }
    
    .show {
      display: block
    }
  </style>
</head>

<body>
  <div class="navbar">
    <div class="dropdown">
      <button onclick="my1Function()" class="dropbtn dropbtn1">Dropdown <i class="fas fa-caret-down"></i></button>
      <div id="myDropdown1" class="dropdown-content dropdown-content1">

      </div>
    </div>

    <div class="dropdown">
      <button onclick="my2Function()" class="dropbtn dropbtn2">Dropdown <i class="fas fa-caret-down"></i></button>
      <div id="myDropdown2" class="dropdown-content dropdown-content2">

      </div>
    </div>

    <div class="dropdown">
      <button onclick="my3Function()" class="dropbtn dropbtn3">Dropdown <i class="fas fa-caret-down"></i></button>
      <div id="myDropdown3" class="dropdown-content dropdown-content2">

      </div>
    </div>
  </div>
  <script>
    function my1Function() {
      document.getElementById("myDropdown1").classList.toggle("show");
    }

    function my2Function() {
      document.getElementById("myDropdown2").classList.toggle("show");
    }

    function my3Function() {
      document.getElementById("myDropdown3").classList.toggle("show");
    }
    window.onclick = function(event) {
      if (!event.target.matches('.dropbtn')) {
        var dropdowns = document.getElementsByClassName("dropdown-content");
        var i;
        for (i = 0; i < dropdowns.length; i++) {
          var openDropdown = dropdowns[i];
          if (openDropdown.classList.contains('show')) {
            openDropdown.classList.remove('show');
          }
        }
      }
    }
  </script>
</body>

</html>

Answer №1

To simplify dropdown button functionality, consider using a generic event listener instead of individual onclick events like my1Function.

  1. Hide any currently displayed dropdown content to manage visibility when clicking outside.
  2. Show the specific dropdown content related to the clicked button.

<!DOCTYPE HTML>
<html>

<head>
  <style>
    * {
      box-sizing: border-box;
    }
    
    body {
      margin: 0;
    }
    
    .navbar {
      width: 100%;
      padding: 0 10% 0 10%;
      overflow: hidden;
      box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.16), 0 2px 10px 0 rgba(0, 0, 0, 0.12);
    }
    
    .dropbtn {
      font-size: 16px;
      border: none;
      outline: none;
      padding: 21.5px 20px;
      background-color: inherit;
      margin: 0;
      cursor: pointer;
      font-weight: bolder;
      color: #2d3436;
    }
    
    .dropdown {
      float: left;
    }
    
    .dropdown-content {
      display: none;
      position: absolute;
      background-color: #fff;
      min-width: 460px;
      box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.16), 0 2px 10px 0 rgba(0, 0, 0, 0.12);
      height: 450px;
    }
    
    .show {
      display: block
    }
  </style>
</head>

<body>
  <div class="navbar">
    <div class="dropdown">
      <button class="dropbtn dropbtn1">Dropdown 1<i class="fas fa-caret-down"></i></button>
      <div id="myDropdown1" class="dropdown-content dropdown-content1">
      </div>
    </div>

    <div class="dropdown">
      <button class="dropbtn dropbtn2">Dropdown 2<i class="fas fa-caret-down"></i></button>
      <div id="myDropdown2" class="dropdown-content dropdown-content2">

      </div>
    </div>

    <div class="dropdown">
      <button class="dropbtn dropbtn3">Dropdown 3<i class="fas fa-caret-down"></i></button>
      <div id="myDropdown3" class="dropdown-content dropdown-content2">

      </div>
    </div>
  </div>
  <script>
    window.addEventListener('click', function(event) {
      // Hide any open dropdown content
      const dropdownContents = document.querySelectorAll('.dropdown-content')
      dropdownContents.forEach(content => {
        content.classList.remove('show');
      });

      // Show the dropdown content respective to the clicked button
      if (event.target.matches('.dropbtn')) {
        event.target.nextElementSibling.classList.add('show');
      }
    })
  </script>
</body>

</html>

Answer №2

If I were to implement a dropdown menu, I would use the following structure:

<nav>
    <ul class="my-nav">
        <li>
            <details class="dropdown">
                <summary>Click here for more options</summary>
                <ul>
                    <li><a href="#option1">Option 1</a></li>
                    <li><a href="#option2">Option 2</a></li>
                </ul>
            </details>
        </li>
        <li>
            <details class="dropdown">
                <summary>Another dropdown menu</summary>
                <ul>
                    <li><a href="#menu-item1">Menu Item 1</a></li>
                    <li><a href="#menu-item2">Menu Item 2</a></li>
                </ul>
            </details>
        </li>
    </ul>
</nav>

Of course, each dropdown would have its own unique content and links. Here is the accompanying JavaScript code:

var nav = document.querySelector('.my-nav');
nav.addEventListener('toggle', function (event) {

    // Only execute if dropdown is being opened
    if (!event.target.open) return;

    // Close any other open dropdowns
    var dropdowns = nav.querySelectorAll('.dropdown[open]');
    Array.prototype.forEach.call(dropdowns, function (dropdown) {
        if (dropdown === event.target) return;
        dropdown.removeAttribute('open');
    });

}, true);

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

What steps should be taken to fix the sinopia installation error?

While operating on redhat5.9, I encountered an exception related to 'make'. I am curious about what they are trying to create. It seems like it's related to JavaScript. [root@xxxx bin]# npm install -g sinopia --python=/usr/local/clo/ven/pyt ...

Placing a user's username within an ejs template using express and node.js

Currently, I am attempting to integrate the username into a layout using ejs templating with node and express. Below are the steps I have taken: Mongodb model: const mongoose = require('mongoose') const Schema = mongoose.Schema; var uniqueValid ...

How to bring in images from a local source in a React.js file

I've been looking into relative paths and absolute paths, but I'm having trouble importing local images correctly. My main objective is to create a React slideshow using these images. Why does it keep trying to find the images in the "components" ...

Should we enable client-side validation and unobtrusive JavaScript in the Web.config file?

I'm currently working on an ASP MVC application, where all form and UI code is written in AngularJS for validation purposes. I didn't use any HTML helpers. Do I need to include the entries ClientValidationEnabled and UnobtrusiveJavaScriptEnabled ...

Unable to designate the drop-down option as the default selection

Can anyone help me with setting a default drop-down value using JavaScript? I have been struggling to achieve this. You can find my code on jsFiddle <div ng-controller="csrClrt"> <div ng:repeat="(key, item) in items track by $index"> ...

I encounter issues with HTML input fields becoming unresponsive whenever I attempt to apply CSS filters in IE8 for stretching the background

When I wanted to stretch a background image on my website so that it always fills the available window area regardless of resolution, I initially used background-size:cover;. Unfortunately, Internet Explorer doesn't seem to support valid CSS, so I had ...

Ajax cannot seem to come to a resolution

After completing my learning on Ajax, I decided to work on a simple project - a port scanner. However, I am facing issues with it as it is not working properly. The only message that pops up is 'Scan started' and I can't figure out what the ...

Fill the list items with values from the given array

I have an array called var array = ["one", "two"]; and I want to display each element in a separate list item. The desired output is: <li>Number one</li> <li>Number two</li> However, the current output is: <li>Number onetw ...

Tips for creating a mandatory textarea input field

It's pretty straightforward - I have a textarea that is set to required, but it only alerts the user if you actually click inside the text area. If you try to submit without clicking inside, it won't prompt the alert. Take a look at this Fiddle ...

Error: The "map" property cannot be read if it is undefined in a Django and React application

While I was following the react and django tutorial, I encountered an issue when I added some code for concern with. The error message 'Cannot read property 'map' of undefined' keeps getting thrown. The error location is pointed out ...

Arrange the header and input within a div using flexbox to achieve different alignments

I need help aligning the header section vertically and ensuring responsiveness. Using margin-top isn't fully responsive, so I want to align the header at the beginning of the input field. { margin: 0px; padding: 0px; color: white; } #h ...

Use jQuery to assign a value of "true" when a checkbox is

Can you guide me on how to use jQuery to implement a click function that sets the status value to 'true' if a checkbox is checked, and 'false' if it's not checked? If Checkbox 1 is checked, Status 1 should be set to true. Similarl ...

Tips for capturing text input from a Quill rich text editor div

My attempt to retrieve the content entered in Quill editor's editor div using jQuery codes is not proving successful. Although it works for other text inputs, it fails to do so for the editor div. Below is a demonstration of the issue: $(function() ...

Exclusive to Safari: Codesandbox is experiencing difficulties retrieving data from the localhost server

Would you mind helping me out with this technical issue I'm facing? For the server/API, I am using this link. As for the mock website, it can be found at this URL. The problem is that, in my code, I'm using axios to fetch data from the locally h ...

Implementing JavaScript Functions to Trigger Control Key and Plus/Minus Events

In my project, I have a unique set of selectors called A+. By clicking on the A+ button, it has been programmed to initiate the control plus event. Similarly, within the same interface, I also have an A- button that activates the control minus event when ...

What is the method of posting to PHP using JavaScript without utilizing Ajax?

My current code involves a drag and drop file uploader to PHP using ajax, but it seems that my web host does not support ajax. Is there an alternative method to achieve this without using ajax? Specifically, I am facing issues with the UploadFile functio ...

Hide the button with jQuery Ajax if the variable is deemed acceptable upon submission

I need to figure out how to hide the submit button if the email entered is the same as the one in the database from action.php. Can anyone help me with integrating this functionality into my existing code? <form onsubmit="return submitdata();"> ...

Is it possible to receive returned string values using fetch()?

I have implemented a fetch method in my separate register.js file to handle registration on the front end. However, I am encountering an error when trying to POST the data and receive the following message in the browser console: "Uncaught (in promise) Syn ...

The React server-side rendering isn't reflecting changes made on the client-side route

Upon the first refresh, both the server and client side are updated; however, subsequent updates only affect the client side when switching pages with react router. For instance, refreshing the page or entering a new URL causes changes on the server and t ...

Is there a way to duplicate and insert a function in node.js if I only have its name?

I'm currently working on a code generation project and I've encountered a problem that I initially thought would be easy to solve. However, it seems to be more complicated than I anticipated. My task involves taking a method name as input, naviga ...