Issue with Dropdown Menu functionality while using multiple dropdown options

I am currently experimenting with dropdown menus from W3Schools and have encountered an issue when trying to implement two dropdown options. The code works fine for a single dropdown, but when I try to add a second one using GetElementsByClassName instead of GetElementById, it doesn't function as expected. Here is the link to the problematic code.

code.html

<ul>
<li><a class="active" href="#home">Home</a></li>
<li><a href="#news">News</a></li>
<li class="dropdown">
<a href="javascript:void(0)" class="dropbtn"  onclick="myFunction()">Dropdown1</a>
<div class="dropdown-content myDropdown">
  <a href="#">Link 1</a>
  <a href="#">Link 2</a>
  <a href="#">Link 3</a>
</div>
</li>
<li class="dropdown">
<a href="javascript:void(0)" class="dropbtn" onclick="myFunction()">Dropdown2</a>
<div class="dropdown-content myDropdown">
  <a href="#">Link 1</a>
  <a href="#">Link 2</a>
  <a href="#">Link 3</a>
 </div>
</li>
 function myFunction() {
   document.getElementsByClassName("myDropdown").classList.toggle("show");
}


 window.onclick = function(e) {
 if (!e.target.matches('.dropbtn')) {

var dropdowns = document.getElementsByClassName("dropdown-content");
for (var d = 0; d < dropdowns.length; d++) {
  var openDropdown = dropdowns[d];
  if (openDropdown.classList.contains('show')) {
    openDropdown.classList.remove('show');
  }
}
}
}

Answer №1

The reason your fiddle was not working is due to the fact that myFunction was not defined (you can see this error in the developer console of your browser). This is because jsFiddle wraps your javascript code.

<script type="text/javascript">//<![CDATA[
window.onload=function(){
  // Your code goes here
}//]]> 
</script>

Therefore, your function will only be accessible within the scope of the window.onload function and not outside of it. To make your function available globally in your html, you need to define it in the global scope which is window.

Once you do this, you can interact with your function and see that

document.getElementsByClassName("myDropdown")
returns all dropdown elements as an array. The solution is simple - add a this parameter when calling myFunction in the html. Then, in your function, toggle the "show" class on the next element.

<li class="dropdown">
    <a href="javascript:void(0)" class="dropbtn" onclick="myFunction(this)">Dropdown1</a>
    <div class="dropdown-content myDropdown">
      <a href="#">Link 11</a>
      <a href="#">Link 21</a>
      <a href="#">Link 31</a>
    </div>
</li>

function myFunction(el) {
  el.nextElementSibling.classList.add("show");
}

Another issue you might encounter is that when you click on Dropdown1 and then on Dropdown2, the first dropdown doesn't disappear. You can view a working demo here :)

Answer №2

I made a modification to the code by assigning unique IDs to both dropdown menus.

        <ul>
    <li><a class="active" href="#home">Home</a></li>
    <li><a href="#news">News</a></li>
    <li class="dropdown">
    <a href="javascript:void(0)" class="dropbtn"  onclick="myFunction(this)">Dropdown1</a>
    <div class="dropdown-content myDropdown" id="dropdown1">
      <a href="#">Link 1</a>
      <a href="#">Link 2</a>
      <a href="#">Link 3</a>
    </div>
    </li>
    <li class="dropdown">
    <a href="javascript:void(0)" class="dropbtn" onclick="myFunction(this)">Dropdown2</a>
    <div class="dropdown-content myDropdown" id="dropdown2">
      <a href="#">Link 1</a>
      <a href="#">Link 2</a>
      <a href="#">Link 3</a>
     </div>
    </li>
    </ul>

    <h3>Dropdown Menu inside a Navigation Bar</h3>
    <p>Click on the "Dropdown" link to see the dropdown menu.</p>




    <script>
    /* When the user clicks on the button, 
    toggle between hiding and showing the dropdown content */
    function myFunction(a) {
        //alert(a.nextElementSibling.id);    
        var divId = a.nextElementSibling.id;
        document.getElementById(divId).classList.toggle("show");
    }

    // Close the dropdown if the user clicks outside of it
    window.onclick = function(e) {
      if (!e.target.matches('.dropbtn')) {

        var dropdowns = document.getElementsByClassName("dropdown-content");
        for (var d = 0; d < dropdowns.length; d++) {
          var openDropdown = dropdowns[d];
          if (openDropdown.classList.contains('show')) {
            openDropdown.classList.remove('show');
          }
        }
      }
    }
    </script>

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

I'm intrigued: what type of syntax is Facebook's polling service utilizing in the callback?

While monitoring the Network Monitor on Chrome's developer tool, I observed how Facebook updates content on their news feed. All AJAX responses start with the following: for (;;);{"__ar":1,"payload":[]} I'm curious about what the for(;;); piec ...

The .map() function seems to be missing some data when fetching from the database in a Node.js

I am currently tackling an exercise for a Bootcamp, and the function I am using is not yielding the desired outcome. The objective is to query the database with a first name or a part of a first name. While I can successfully execute the DB query and retri ...

Exploring the power of QueryTask in ArcGIS JS API 3 for running multiple queries

When using QueryTask in ArcGIS JS Api 3, I encountered a challenge where I needed to execute multiple queries in one call. After referencing the documentation, I realized that this functionality was not directly supported. This is my current implementatio ...

The page loads successfully at first, but upon refreshing, a 404 error occurs when using Zeit, Nextjs, and now

After recently updating from now v1 to v2, I encountered an issue where my pages would return a 404 error when reloading after pushing to production using now --prod. While everything worked fine locally with now dev, the routing seemed to be causing confu ...

I encountered a CORS policy error while using React. What steps can I take to effectively manage and resolve this

INDEX.JS import express from "express"; import { APP_PORT } from "./config"; import db from "./database"; import cors from "cors"; import bodyParser from "body-parser"; import Routes from "./routes&quo ...

Aligning a set of list items horizontally within an unordered list is a great way to maintain a clean

I'm struggling with centering the alignment of li elements within a ul. Below is the excerpt from my code: ul.nav { width: 1000px; margin: 0 auto; list-style-type: none; } .nav li { float: left; width: 300px; } #government { clear: left ...

Chrome isn't showing the Background Image

I am currently working on coding a basic HTML/CSS page and I want to include a background-image within a div element that links to a URL. Interestingly, my code is functioning properly in Safari (Mac) and Firefox but unfortunately not showing the desired r ...

Step by step guide to building an exclusive form input field in HTML that allows only a single response

Is there a way in HTML to set up a text input or password input on a <form> that requires a specific value, such as "apples"? The form should only submit if the person entering their information types "apples" into the designated input field. ...

What is the correct way to assign a $scope variable after a successful ajax call?

Currently, I am working with Symfony and AngularJs 1.6.8 along with Symfony 3.4. Below is the configuration setup that I have: base.html.twig <html lang="en" data-ng-app="CeocApp" ng-controller="CeocController"> //css for the app <link id="ng ...

Refresh the cumulative URL count in JavaScript following the completion of an AJAX submission

My shopping cart is filled with URLs that include a total key: The total value in the cart is <span id="cart-status" >1805.32</span> <ul> <li><a href='/Store/Category/Products?user=ADMIN&total=1805.32'& ...

Customize the element of the root node of a MUI component using the styled()

I am trying to implement the "component" prop with a MUI component (such as ListItem) using the styled() API. However, I am facing an issue where it says that "component" is not a valid prop. Can someone guide me on how to correctly achieve this? I have se ...

What is the proper way to add comments within CSS code inline?

Can anyone provide instructions on how to comment an inline css property, such as height, in the following code snippet? <div style="width:100%; height:30%;"> Any help is appreciated. Thank you! ...

Select elements in jQuery using both a specific selector and a negative selector

I am currently working with a JQuery function that highlights a specific word and scrolls to it: $('article.node--article p, .video-title').highlightWordAndScroll({ words : search_word, tag : '<span class="found_key ...

Tips for inserting an image within a horizontal list of items

Struggling to find a solution here. I have a menu with a unique bar design between list elements, featuring breaks at the top and bottom. I attempted to use li:after in the CSS to insert an image, but encountered issues with padding and margin. Below is t ...

The link in the drop down select is not functioning in IE8/9. When trying to open the drop down select link, an

Could use some help with IE8 and 9 compatibility, can't seem to find a solution. This code works smoothly on Chrome, FF, and Safari. There are two dropdown menus, each with two links. Every dropdown menu has its own "Buy Now" button. Upon selecting ...

Can you recall the name given to characteristics that do not have any value assigned to them (e.g. "checked" and "selected")?

There is a specific group of attributes in HTML that do not accept a value. For example, the checked attribute for the <input> tag and the selected attribute for the <option> tag fall into this category. Do you know what term is used to refer ...

Using promises and the fetch function to connect to a database

I am attempting to utilize promises with the fetch() function in order to access MongoDB from the front-end, but I am encountering some issues. var Promise = () => ( new Promise((resolve, reject) => { //perform certain actions, make requests ...

Attaching Picture From Array To Vue

Is it possible for me to request assistance? I'm wondering how to bind an image to a vue component or more simply, how do you render an image from an array in vue? Allow me to share my code with you and explain in detail how I have approached this. W ...

Extension for Chrome - Personalized pop-up notification when page loads

I am looking to create a custom alert box that triggers on page load instead of the default one, which I find unattractive and possibly irritating for users. alert('hello'); My current approach involves the following code: manifesto.js "cont ...

How come the back button does not initiate client-side navigation in a Next.js application?

In my Next.js application utilizing GraphQL to fetch articles from a server, I encountered an issue with dynamic routing when reloading the page while on an article and attempting to navigate back. The usual scenario works as expected: Index -> [slug] ...