Display a single submenu on mouseover using Javascript

Hello there,

I have been working on creating a small menu using only Javascript, but I am facing an issue where the onmouseover event is displaying all submenus instead of just one.

Below is the section of code that is supposed to change style.display to block:

var ul = document.getElementById("navMainId"),
    var liDropdown = ul.getElementsByClassName("dropdown");

for (var i = 0; i < liDropdown.length; i++) {
    liDropdown[i].style.display = "inline-block";

    liDropdown[i].onmouseover = function () {
        var ul = document.getElementById("navMainId"),
            dropdown = ul.getElementsByClassName("dropdown-content");


        for (var i = 0; i < dropdown.length; i++) {
            dropdown[i].style.display = "block";                
        }
    }
    liDropdown[i].onmouseleave = function () {
        var ul = document.getElementById("navMainId"),
            dropdown = ul.getElementsByClassName("dropdown-content");

        for (var i = 0; i < dropdown.length; i++) {
            dropdown[i].style.display = "none";
        }
    }
}

Any ideas on how I can modify the code to make it function correctly?

You can view the complete code on Fiddle here (apologies for the mess): https://jsfiddle.net/apvsnzt5/1/

Answer №1

I have made some necessary changes to the fiddle:

https://jsfiddle.net/qwerty123/5/

The key adjustment required was modifying

        dropdown = ul.getElementsByClassName("dropdown-content");

to

        dropdown = this.getElementsByClassName("dropdown-content");

This change ensures that it selects "this" (which is the LI being hovered over) instead of searching for "dropdown-content" within the UL element.

Remember to apply the same modification to the onmouseleave event as well.

Answer №2

It appears that there is a mistake in referencing the container when hovering over with the mouse. Ensure you provide specific content based on the position of your mouse.

var dropdown = this.getElementsByClassName("dropdown-content");

Check out the revised fiddle here

Answer №3

Make sure to include the following in your CSS section

.dropdown-content{
      display:none ! important;
    }
    a:hover+.dropdown-content{
      display:block ! important;
    }

Your code should now be working properly.

var menuCont = document.createElement("div");
    document.body.appendChild(menuCont);


    var ulMain = document.createElement("ul");
    menuCont.appendChild(ulMain); 
    ulMain.className = "navMain";
    ulMain.id = "navMainId";

    /****** MENU  ******/


    // Software
    var liSoftware = document.createElement("li");
    liSoftware.className = "menu dropdown";
    ulMain.appendChild(liSoftware);
    var aSoftware = document.createElement("a");
    aSoftware.className = "menuName dropbtn";
    aSoftware.href = "#";
    aSoftware.textContent = "Test1";
    liSoftware.appendChild(aSoftware);

    // GeCoSoft
    var liGeco = document.createElement("li");
    liGeco.className = "menu dropdown";
    ulMain.appendChild(liGeco);
    var aGeco = document.createElement("a");
    aGeco.className = "menuName dropbtn";
    aGeco.href = "#";
    aGeco.textContent = "Test2";
    liGeco.appendChild(aGeco);


    /******* Submenu *******/

    // Software Sub

    var divSubSoft = document.createElement("div");
    divSubSoft.className = "dropdown-content";
    liSoftware.appendChild(divSubSoft);

    var aSub1 = document.createElement("a"),
        aSub2 = document.createElement("a");

    aSub1.className = "menuSubName";
    aSub1.textContent = "SubMenu1";
    aSub1.href = "#";
    aSub2.className = "menuSubName";
    aSub2.textContent = "SubMenu2";
    aSub2.href = "#";

    divSubSoft.appendChild(aSub1);
    divSubSoft.appendChild(aSub2);

    // Gecosoft Sub

    var divSubGeco = document.createElement("div");
    divSubGeco.className = "dropdown-content";
    liGeco.appendChild(divSubGeco);

    var aSub3 = document.createElement("a"),
        aSub4 = document.createElement("a");

    aSub3.className = "menuSubName";
    aSub3.textContent = "Submenu3";
    aSub3.href = "#";
    aSub4.className = "menuSubName";
    aSub4.textContent = "SubMenu4"
    aSub4.href = "#";

    divSubGeco.appendChild(aSub3);
    divSubGeco.appendChild(aSub4);

    /****** MENU STYLE ******/

    var i = "";


    ulMain.style.listStyleType = "none"; 
    ulMain.style.margin = "0px";  
    ulMain.style.padding = "0px";     
    ulMain.style.overflow = "hidden";
    ulMain.style.backgroundColor = "rgb(232, 225, 225)";

    var ul = document.getElementById("navMainId"),
        li = ul.getElementsByTagName("li");

    for (var i = 0; i < li.length; i++) { 
        li[i].style.cssFloat = "left";
    }

    var a = ul.getElementsByTagName("a"); 

    for (var i = 0; i < a.length; i++) {
            a[i].style.display = "inline-block";
            a[i].style.color = "black";
            a[i].style.textAlign = "center"; 
            a[i].style.padding = "14px 16px";  
            a[i].style.textDecoration = "none";
            a[i].onmouseover = function () { 
                this.style.backgroundColor = "rgb(174, 170, 170)";            
            }
            a[i].mouseleave = function () {
                this.style.backgroundColor = "rgb(232, 225, 225)";
            }
    }

/************ Not sure what to do here **************/
    var liDropdown = ul.getElementsByClassName("dropdown"); 

    for (var i = 0; i < liDropdown.length; i++) {
        liDropdown[i].style.display = "inline-block";

        liDropdown[i].mouseover = function () {
            var ul = document.getElementById("navMainId"),
                dropdown = ul.getElementsByClassName("dropdown-content");


            
            for (var i = 0; i < dropdown.length; i++) {
                dropdown[i].style.display = "block";                
            }
        }
        liDropdown[i].mouseleave = function () {
            var ul = document.getElementById("navMainId"),
                dropdown = ul.getElementsByClassName("dropdown-content");

            for (var i = 0; i < dropdown.length; i++) {
                dropdown[i].style.display = "none";
            }
        }
    }

    var divDropCont = ul.getElementsByClassName("dropdown-content");

    for (var i = 0; i < divDropCont.length; i++) {
        divDropCont[i].style.display = "none";
        divDropCont[i].style.position = "absolute";
        divDropCont[i].style.backgroundColor = "#f9f9f9";
        divDropCont[i].style.minWidth = "160px";
        divDropCont[i].style.boxShadow = "0px 8px 16px 0px rgba(0,0,0,0.2)";
    }

    var aDropCont = ul.getElementsByClassName("menuSubName");   

    for (var i = 0; i < aDropCont.length; i++) {
        aDropCont[i].style.color = "black";
        aDropCont[i].style.padding = "12px 16px";
        aDropCont[i].style.textDecoration = "none";
        aDropCont[i].style.display = "block";
        aDropCont[i].style.textAlign = "left";
        aDropCont[i].onmouseover = function () {
            this.style.backgroundColor = "rgb(174, 170, 170)";
        }
        aDropCont[i].mouseleave = function () {
            this.style.backgroundColor = "rgb(249, 249, 249)";
        }
    }
.dropdown-content{
  display:none ! important;
}
a:hover+.dropdown-content{
  display:block ! important;
}

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 is the limit on the amount of input data (in CSV or JSON format) that can be used to create a

Attempting to visualize a large dataset using D3.js has posed a challenge for me. The data size is 261 MB with approximately 400,000 rows in CSV format. Even when I attempt to run it with just 100,000 rows, the visualization does not appear on the browser. ...

Arranging JSON data by a specific attribute using JavaScript

As someone who is new to JavaScript, I have been working on some basic exercises. In my current code, I have a JSON data stored in a String that contains information about employees. My goal is to sort this data based on the age attribute and display the o ...

The functionality of the ajax hash navigation feature seems to be malfunctioning

I've been trying to use hashes for my navigation, but everytime the page loads, my script resets the initial hash to #home. It doesn't matter what hash I add in the URL: Here is the script that runs to check if the hash exists and what content t ...

modifying a mongodb array without actually updating it

Currently, I am facing an issue with updating the collection of users whose purchase dates have expired. When I attempt to save the changes, the user's role gets updated successfully but the purchase history does not reflect the changes. Below is the ...

``Please note that the Sinon spy.called method is currently not

Context In my setup, a small server receives data from a machine. Each time a message is received, a function in a dispatcher object is called, which simply logs everything it receives to the console. Issue While I can see the logs in the console, Sinon ...

I am having issues with sendKeys and click() functions in my code. I am unable to access the elements using Protractor's javascript

<input class="form-control validation-field ng-dirty ng-touched ng-invalid" placeholder="Password" type="password"> Despite using the element to retrieve it, I am unable to send keys and no error message is displayed. This issue persists in both Fir ...

What is the best way to vertically align an InputLabel within a MUI Grid item?

I'm trying to vertically center the InputLabel inside a MUI Grid item. Here's what I've attempted: import { FormControl, Grid, Input, InputLabel, TextField } from "@mui/material"; export default function App() ...

Adjust the horizontal position of a text element using CSS

I am faced with a specific challenge where I need to center the text "test" within a text tag using only CSS, without being able to directly change the HTML. <text width="13.89" height="13.89" x="291.46999999999997" y="156.55" transform= ...

How to showcase images and text from an array of objects using React

I'm currently working on a React lightbox that is supposed to display a loop of objects containing images and text. However, I'm facing an issue where the images are not showing up with the corresponding text label as intended. It seems like I a ...

Characteristics within the primary template element of a directive

I'm having an issue with the following directive code: .directive('myDirective', function () { restrict: 'E', replace: true, transclude: true, scope: { label: '@', ngModel: '=', ...

Styling on a device can vary from how it appears on a

Using Ionic2, I have an application with messages. In a browser, the message appears like this: https://i.stack.imgur.com/SyCtM.png However, when running on either an Android or iOS device, it looks different: https://i.stack.imgur.com/i0RdO.png The di ...

Tips for ensuring the server only responds after receiving a message from the client in a UDP Pinger system using sockets

I am in the process of developing a UDP pinger application. The objective is for the client to send a message (Ping) and receive pong back 10 times. However, the challenge lies in sending the messages one at a time instead of all together simultaneously. T ...

Breaking apart a string that consists of boolean values

Presented below is a JavaScript function function cmd_parse( cmd ) { return cmd.split( /\s+/ ); } For instance, when calling the function like this words = cmd_parse("hello jay true"); The output would be words[0]="hello" words[1]="jay" wor ...

Connect ngx-time picker to form input in Angular

Currently, I have successfully implemented Angular material date pickers in my project, however, I am facing a challenge with integrating time pickers as it is not natively supported by Angular Material for version 8. To address this issue, I am utilizing ...

JQuery: Creating a visually striking screen flash

How can I make the window or page flash/blink using JQuery or plain JavaScript? I also want to get the tab to flash at the same time. Currently, the code I have is: var flash = true; var alert = setInterval(function(){ if (flash) //doFlash ...

Please submit information that is not already filled out in the text fields

I am looking to create a table with text fields and buttons as shown below: <table border="1"> <tr> <td>name</td> <td>id</td> <td>icon</td> <td> </td> & ...

Unexpected Display Issue with Angular Select Option

My goal is to implement the Select-Option Input as depicted in the first image link here: https://i.sstatic.net/SVT8R.png However, my current output looks different and I suspect that there may be a conflict between two CSS libraries. It's worth noti ...

Tips for creating CSS styles for a selected input field

I seem to be stuck in a situation where my screen looks similar to the screenshot provided. There are four input elements that I would like to have bordered just like in the image, complete with a circled tick mark. I've managed to create these four i ...

Can you explain the distinction between using single and double quotes in my JavaScript and CSS code?

Is there a significant distinction between using single or double quotes in JS and CSS? Does it depend on personal preference, or are there certain instances where one is preferred over the other? In W3Schools, they employ single quotes for url('&apo ...

What is the process of installing an npm module from a local directory?

I recently downloaded a package from Github at the following link: list.fuzzysearch.js. After unzipping it to a folder, I proceeded to install it in my project directory using the command: npm install Path/to/LocalFolder/list.fuzzysearch.js-master -S Howe ...