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

A unique technique for creating a stunning visual effect with images using

Can anyone help me with this issue: Check out this animated GIF The images in my project are overlapping when scrolling! How can I achieve a similar effect for my images? Is there a tutorial or plugin available for this? Here is the current code sn ...

Guide on redirecting to a new domain using a cookie in Express.js

I am working on a web app using Express on Node and I want to add a proxy login feature that allows users to be automatically logged in and redirected to another site after logging into my site. Within my routing function, I have the following code: res ...

Utilizing AngularJS to create a vertical calendar

Looking to create a vertical navigation displaying the date and day for the current week using angularjs. When clicking on the navigation div, I want an alert with the selected date to appear. I attempted this in Plunker using various templates, but was u ...

JavaScript Tab Fade Effect

I have a tab system that utilizes JavaScript to switch tabs. I am trying to implement a fade in and out effect when switching tabs. The current JavaScript simply adds or removes the clicked tab selected by the user. I have managed to partially achieve the ...

The chosen value remains constant even after altering the selected option

I am trying to create a scroll-down bar that allows users to select different options, and once an option is selected, its value should appear in the bar. However, I'm facing an issue where the value does not change according to the selection: const [ ...

Navigating HTML with Node.js and Express.js

I have been working on routing multiple HTML pages in my project. The index.html file loads without any issues, but when I try to load raw.html, an error message pops up: Error: Failed to lookup view "error" in views directory Below is part of my app.j ...

Tips for converting a URL to the correct route in emberjs when the location type is set to history

After creating a basic Ember.js application and setting the router location type to 'history', I encountered an issue with the generated URLs. Instead of the expected URL format like http://localhost/#/post/1, the Ember.js application was changi ...

Tips for activating the default 500 error page in Next.js

I'm having trouble getting Next.js to display its default 500 error page. While most sources discuss creating a custom error page, the Next.js documentation only briefly references their built-in 500 error page. I want the default page to show up when ...

Using Javascript to display or conceal a specific child element within a loop, based on which parent element has been clicked

I need assistance with creating a grid of projects where clicking on a specific 'project' in the loop will display the corresponding 'project_expanded' div, while hiding all other 'project_expanded' divs. My initial plan was ...

Turn on the text field when the enter key is pressed

I've searched online for solutions, but none of them have resolved my issue. Upon loading my page, I am able to successfully have my JS file select the first textfield. However, I am struggling with getting it to proceed to the next textfield when th ...

Form a column containing both row object data and html code elements

I am in the process of creating a unique column within my table, allowing me to execute specific actions and generating HTML code based on the object defining the row. Being new to Angular, I believe I should utilize $compile, but I am unsure of how to pr ...

Transmitting the character symbol '&' within a string from Angular to PHP

My goal is to transmit a string, such as "the cat & the dog", from Angular to PHP using GET method. I have used encodeURI(note) in Angular and in PHP $note = $_GET['note']; $note = mysql_real_escape_string($note); However, when it gets inse ...

Change hyperlink text color on Android CheckBox

I am having a CheckBox with two links embedded in the text. The text is set using the following code: String htmlText = "Accept <a href='someUrl'>Terms and Conditions</a> and <a href='anotherUrl'>Privacy Policy&l ...

HTML - maintain centered text positioning while implementing padding on the left side

Here are the HTML and CSS code snippets I am working with: #page { background-color: #000; color: #fff; height: 360px; width: 360px; min-height: 100%; } #viewport { font-size: 20pt; text-align: center; } .taskTitle { height: 13%; fon ...

Achieving a transparent inner box-shadow effect on hover: a step-by-step guide

Is there a way to make the black ring transparent upon hover by changing box-shadow: 0 0 0 5px #000, 0 0 0 10px green to box-shadow: 0 0 0 5px transparent, 0 0 0 10px green? It doesn't seem to be working for me. Any suggestions on how to achieve this ...

Accordion styling using CSS

My current issue lies with setting the style for the contents of an accordion. The problem arises when the styles defined in a CSS file do not take effect on the content of my accordion when using the following code along with a separate CSS file: <scr ...

Xap or js Silverlight media player

Currently developing a Silverlight video player, I stumbled upon the JW Player for inspiration. I know that Silverlight apps are typically contained within .xap files, but JW Player utilizes JavaScript scripts to implement Silverlight logic. Can you plea ...

After the recent update to version 4.2.0 of @material-ui/core, unexpected react hook errors have been

Currently, I am working on an electron application that utilizes react and material-ui. Recently, I made the decision to update material-ui to version 4.2.0. As a result of this update, two lines were added to my dependencies in the package.json. "@materi ...

Preserve HTML element states upon refreshing the page

On my webpage, I have draggable and resizable DIVs that I want to save the state of so they remain the same after a page refresh. This functionality is seen in features like Facebook chat where open windows remain open even after refreshing the page. Can ...

Retrieve data quickly and navigate directly to specified div element on page

I am facing an issue with scrolling on my website. While it currently works fine, I would like to make the scrolling instant without any animation. I want the page to refresh and remain in the same position as before, without automatically scrolling to a s ...